diff --git a/codegen/gradle.properties b/codegen/gradle.properties index 99fe933907c..af9b7ae7f42 100644 --- a/codegen/gradle.properties +++ b/codegen/gradle.properties @@ -1 +1,2 @@ -smithyVersion=1.21.0 +smithyVersion=1.23.1 +smithyGradleVersion=0.6.0 diff --git a/codegen/protocol-test-codegen/build.gradle.kts b/codegen/protocol-test-codegen/build.gradle.kts index f1e86e2e574..e816675404a 100644 --- a/codegen/protocol-test-codegen/build.gradle.kts +++ b/codegen/protocol-test-codegen/build.gradle.kts @@ -28,7 +28,8 @@ buildscript { } plugins { - id("software.amazon.smithy") version "0.5.3" + val smithyGradleVersion: String by project + id("software.amazon.smithy") version smithyGradleVersion } dependencies { diff --git a/codegen/sdk-codegen/build.gradle.kts b/codegen/sdk-codegen/build.gradle.kts index 8b33071321d..ff2794735b4 100644 --- a/codegen/sdk-codegen/build.gradle.kts +++ b/codegen/sdk-codegen/build.gradle.kts @@ -33,7 +33,8 @@ buildscript { } plugins { - id("software.amazon.smithy") version "0.5.3" + val smithyGradleVersion: String by project + id("software.amazon.smithy") version smithyGradleVersion } dependencies { diff --git a/codegen/smithy-aws-go-codegen/src/main/java/software/amazon/smithy/aws/go/codegen/JsonShapeDeserVisitor.java b/codegen/smithy-aws-go-codegen/src/main/java/software/amazon/smithy/aws/go/codegen/JsonShapeDeserVisitor.java index 96d06a41b1c..2bba51d5dd8 100644 --- a/codegen/smithy-aws-go-codegen/src/main/java/software/amazon/smithy/aws/go/codegen/JsonShapeDeserVisitor.java +++ b/codegen/smithy-aws-go-codegen/src/main/java/software/amazon/smithy/aws/go/codegen/JsonShapeDeserVisitor.java @@ -231,8 +231,9 @@ protected void deserializeUnion(GenerationContext context, UnionShape shape) { symbolProvider.toMemberName(member), symbol.getNamespace() ).build(); + String serializedMemberName = getSerializedMemberName(member); - writer.openBlock("case $S:", "", member.getMemberName(), () -> { + writer.openBlock("case $S:", "", serializedMemberName, () -> { writer.write("var mv $P", targetSymbol); target.accept(getMemberDeserVisitor(member, "mv")); diff --git a/codegen/smithy-aws-go-codegen/src/main/java/software/amazon/smithy/aws/go/codegen/JsonShapeSerVisitor.java b/codegen/smithy-aws-go-codegen/src/main/java/software/amazon/smithy/aws/go/codegen/JsonShapeSerVisitor.java index 2485913ddda..311318cd3fd 100644 --- a/codegen/smithy-aws-go-codegen/src/main/java/software/amazon/smithy/aws/go/codegen/JsonShapeSerVisitor.java +++ b/codegen/smithy-aws-go-codegen/src/main/java/software/amazon/smithy/aws/go/codegen/JsonShapeSerVisitor.java @@ -235,9 +235,10 @@ protected void serializeUnion(GenerationContext context, UnionShape shape) { symbolProvider.toMemberName(member), symbol.getNamespace() ).build(); + String serializedMemberName = getSerializedMemberName(member); writer.openBlock("case *$T:", "", memberSymbol, () -> { - writer.write("av := object.Key($S)", member.getMemberName()); + writer.write("av := object.Key($S)", serializedMemberName); target.accept(getMemberSerVisitor(member, "uv.Value", "av")); }); } diff --git a/internal/protocoltest/awsrestjson/api_op_MalformedAcceptWithGenericString.go b/internal/protocoltest/awsrestjson/api_op_MalformedAcceptWithGenericString.go index aec31720fa7..a4ab2967568 100644 --- a/internal/protocoltest/awsrestjson/api_op_MalformedAcceptWithGenericString.go +++ b/internal/protocoltest/awsrestjson/api_op_MalformedAcceptWithGenericString.go @@ -25,12 +25,12 @@ func (c *Client) MalformedAcceptWithGenericString(ctx context.Context, params *M } type MalformedAcceptWithGenericStringInput struct { - Payload []byte - noSmithyDocumentSerde } type MalformedAcceptWithGenericStringOutput struct { + Payload *string + // Metadata pertaining to the operation's result. ResultMetadata middleware.Metadata diff --git a/internal/protocoltest/awsrestjson/api_op_MalformedSet.go b/internal/protocoltest/awsrestjson/api_op_PostUnionWithJsonName.go similarity index 57% rename from internal/protocoltest/awsrestjson/api_op_MalformedSet.go rename to internal/protocoltest/awsrestjson/api_op_PostUnionWithJsonName.go index e3bf083812d..2cc256fb8dd 100644 --- a/internal/protocoltest/awsrestjson/api_op_MalformedSet.go +++ b/internal/protocoltest/awsrestjson/api_op_PostUnionWithJsonName.go @@ -5,46 +5,50 @@ package awsrestjson import ( "context" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + "github.com/aws/aws-sdk-go-v2/internal/protocoltest/awsrestjson/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -func (c *Client) MalformedSet(ctx context.Context, params *MalformedSetInput, optFns ...func(*Options)) (*MalformedSetOutput, error) { +// This operation defines a union that uses jsonName on some members. +func (c *Client) PostUnionWithJsonName(ctx context.Context, params *PostUnionWithJsonNameInput, optFns ...func(*Options)) (*PostUnionWithJsonNameOutput, error) { if params == nil { - params = &MalformedSetInput{} + params = &PostUnionWithJsonNameInput{} } - result, metadata, err := c.invokeOperation(ctx, "MalformedSet", params, optFns, c.addOperationMalformedSetMiddlewares) + result, metadata, err := c.invokeOperation(ctx, "PostUnionWithJsonName", params, optFns, c.addOperationPostUnionWithJsonNameMiddlewares) if err != nil { return nil, err } - out := result.(*MalformedSetOutput) + out := result.(*PostUnionWithJsonNameOutput) out.ResultMetadata = metadata return out, nil } -type MalformedSetInput struct { - BlobSet [][]byte - - Set []string +type PostUnionWithJsonNameInput struct { + Value types.UnionWithJsonName noSmithyDocumentSerde } -type MalformedSetOutput struct { +type PostUnionWithJsonNameOutput struct { + + // This member is required. + Value types.UnionWithJsonName + // Metadata pertaining to the operation's result. ResultMetadata middleware.Metadata noSmithyDocumentSerde } -func (c *Client) addOperationMalformedSetMiddlewares(stack *middleware.Stack, options Options) (err error) { - err = stack.Serialize.Add(&awsRestjson1_serializeOpMalformedSet{}, middleware.After) +func (c *Client) addOperationPostUnionWithJsonNameMiddlewares(stack *middleware.Stack, options Options) (err error) { + err = stack.Serialize.Add(&awsRestjson1_serializeOpPostUnionWithJsonName{}, middleware.After) if err != nil { return err } - err = stack.Deserialize.Add(&awsRestjson1_deserializeOpMalformedSet{}, middleware.After) + err = stack.Deserialize.Add(&awsRestjson1_deserializeOpPostUnionWithJsonName{}, middleware.After) if err != nil { return err } @@ -78,7 +82,7 @@ func (c *Client) addOperationMalformedSetMiddlewares(stack *middleware.Stack, op if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opMalformedSet(options.Region), middleware.Before); err != nil { + if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPostUnionWithJsonName(options.Region), middleware.Before); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -93,10 +97,10 @@ func (c *Client) addOperationMalformedSetMiddlewares(stack *middleware.Stack, op return nil } -func newServiceMetadataMiddleware_opMalformedSet(region string) *awsmiddleware.RegisterServiceMetadata { +func newServiceMetadataMiddleware_opPostUnionWithJsonName(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - OperationName: "MalformedSet", + OperationName: "PostUnionWithJsonName", } } diff --git a/internal/protocoltest/awsrestjson/api_op_PostUnionWithJsonName_test.go b/internal/protocoltest/awsrestjson/api_op_PostUnionWithJsonName_test.go new file mode 100644 index 00000000000..cd53ad55af3 --- /dev/null +++ b/internal/protocoltest/awsrestjson/api_op_PostUnionWithJsonName_test.go @@ -0,0 +1,306 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package awsrestjson + +import ( + "bytes" + "context" + "github.com/aws/aws-sdk-go-v2/aws" + awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" + "github.com/aws/aws-sdk-go-v2/internal/protocoltest/awsrestjson/types" + smithydocument "github.com/aws/smithy-go/document" + "github.com/aws/smithy-go/middleware" + smithyrand "github.com/aws/smithy-go/rand" + smithytesting "github.com/aws/smithy-go/testing" + smithyhttp "github.com/aws/smithy-go/transport/http" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "io" + "io/ioutil" + "math" + "net/http" + "net/http/httptest" + "net/url" + "strconv" + "testing" +) + +func TestClient_PostUnionWithJsonName_awsRestjson1Serialize(t *testing.T) { + cases := map[string]struct { + Params *PostUnionWithJsonNameInput + ExpectMethod string + ExpectURIPath string + ExpectQuery []smithytesting.QueryItem + RequireQuery []string + ForbidQuery []string + ExpectHeader http.Header + RequireHeader []string + ForbidHeader []string + Host *url.URL + BodyMediaType string + BodyAssert func(io.Reader) error + }{ + // Tests that jsonName works with union members. + "PostUnionWithJsonNameRequest1": { + Params: &PostUnionWithJsonNameInput{ + Value: &types.UnionWithJsonNameMemberFoo{Value: "hi"}, + }, + ExpectMethod: "POST", + ExpectURIPath: "/PostUnionWithJsonName", + ExpectQuery: []smithytesting.QueryItem{}, + ExpectHeader: http.Header{ + "Content-Type": []string{"application/json"}, + }, + BodyMediaType: "application/json", + BodyAssert: func(actual io.Reader) error { + return smithytesting.CompareJSONReaderBytes(actual, []byte(`{ + "value": { + "FOO": "hi" + } + }`)) + }, + }, + // Tests that jsonName works with union members. + "PostUnionWithJsonNameRequest2": { + Params: &PostUnionWithJsonNameInput{ + Value: &types.UnionWithJsonNameMemberBaz{Value: "hi"}, + }, + ExpectMethod: "POST", + ExpectURIPath: "/PostUnionWithJsonName", + ExpectQuery: []smithytesting.QueryItem{}, + ExpectHeader: http.Header{ + "Content-Type": []string{"application/json"}, + }, + BodyMediaType: "application/json", + BodyAssert: func(actual io.Reader) error { + return smithytesting.CompareJSONReaderBytes(actual, []byte(`{ + "value": { + "_baz": "hi" + } + }`)) + }, + }, + // Tests that jsonName works with union members. + "PostUnionWithJsonNameRequest3": { + Params: &PostUnionWithJsonNameInput{ + Value: &types.UnionWithJsonNameMemberBar{Value: "hi"}, + }, + ExpectMethod: "POST", + ExpectURIPath: "/PostUnionWithJsonName", + ExpectQuery: []smithytesting.QueryItem{}, + ExpectHeader: http.Header{ + "Content-Type": []string{"application/json"}, + }, + BodyMediaType: "application/json", + BodyAssert: func(actual io.Reader) error { + return smithytesting.CompareJSONReaderBytes(actual, []byte(`{ + "value": { + "bar": "hi" + } + }`)) + }, + }, + } + for name, c := range cases { + t.Run(name, func(t *testing.T) { + var actualReq *http.Request + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + actualReq = r.Clone(r.Context()) + if len(actualReq.URL.RawPath) == 0 { + actualReq.URL.RawPath = actualReq.URL.Path + } + if v := actualReq.ContentLength; v != 0 { + actualReq.Header.Set("Content-Length", strconv.FormatInt(v, 10)) + } + var buf bytes.Buffer + if _, err := io.Copy(&buf, r.Body); err != nil { + t.Errorf("failed to read request body, %v", err) + } + actualReq.Body = ioutil.NopCloser(&buf) + + w.WriteHeader(200) + })) + defer server.Close() + serverURL := server.URL + if c.Host != nil { + u, err := url.Parse(serverURL) + if err != nil { + t.Fatalf("expect no error, got %v", err) + } + u.Path = c.Host.Path + u.RawPath = c.Host.RawPath + u.RawQuery = c.Host.RawQuery + serverURL = u.String() + } + client := New(Options{ + APIOptions: []func(*middleware.Stack) error{ + func(s *middleware.Stack) error { + s.Finalize.Clear() + s.Initialize.Remove(`OperationInputValidation`) + return nil + }, + }, + EndpointResolver: EndpointResolverFunc(func(region string, options EndpointResolverOptions) (e aws.Endpoint, err error) { + e.URL = serverURL + e.SigningRegion = "us-west-2" + return e, err + }), + HTTPClient: awshttp.NewBuildableClient(), + IdempotencyTokenProvider: smithyrand.NewUUIDIdempotencyToken(&smithytesting.ByteLoop{}), + Region: "us-west-2", + }) + result, err := client.PostUnionWithJsonName(context.Background(), c.Params) + if err != nil { + t.Fatalf("expect nil err, got %v", err) + } + if result == nil { + t.Fatalf("expect not nil result") + } + if e, a := c.ExpectMethod, actualReq.Method; e != a { + t.Errorf("expect %v method, got %v", e, a) + } + if e, a := c.ExpectURIPath, actualReq.URL.RawPath; e != a { + t.Errorf("expect %v path, got %v", e, a) + } + queryItems := smithytesting.ParseRawQuery(actualReq.URL.RawQuery) + smithytesting.AssertHasQuery(t, c.ExpectQuery, queryItems) + smithytesting.AssertHasQueryKeys(t, c.RequireQuery, queryItems) + smithytesting.AssertNotHaveQueryKeys(t, c.ForbidQuery, queryItems) + smithytesting.AssertHasHeader(t, c.ExpectHeader, actualReq.Header) + smithytesting.AssertHasHeaderKeys(t, c.RequireHeader, actualReq.Header) + smithytesting.AssertNotHaveHeaderKeys(t, c.ForbidHeader, actualReq.Header) + if c.BodyAssert != nil { + if err := c.BodyAssert(actualReq.Body); err != nil { + t.Errorf("expect body equal, got %v", err) + } + } + }) + } +} + +func TestClient_PostUnionWithJsonName_awsRestjson1Deserialize(t *testing.T) { + cases := map[string]struct { + StatusCode int + Header http.Header + BodyMediaType string + Body []byte + ExpectResult *PostUnionWithJsonNameOutput + }{ + // Tests that jsonName works with union members. + "PostUnionWithJsonNameResponse1": { + StatusCode: 200, + Header: http.Header{ + "Content-Type": []string{"application/json"}, + }, + BodyMediaType: "application/json", + Body: []byte(`{ + "value": { + "FOO": "hi" + } + }`), + ExpectResult: &PostUnionWithJsonNameOutput{ + Value: &types.UnionWithJsonNameMemberFoo{Value: "hi"}, + }, + }, + // Tests that jsonName works with union members. + "PostUnionWithJsonNameResponse2": { + StatusCode: 200, + Header: http.Header{ + "Content-Type": []string{"application/json"}, + }, + BodyMediaType: "application/json", + Body: []byte(`{ + "value": { + "_baz": "hi" + } + }`), + ExpectResult: &PostUnionWithJsonNameOutput{ + Value: &types.UnionWithJsonNameMemberBaz{Value: "hi"}, + }, + }, + // Tests that jsonName works with union members. + "PostUnionWithJsonNameResponse3": { + StatusCode: 200, + Header: http.Header{ + "Content-Type": []string{"application/json"}, + }, + BodyMediaType: "application/json", + Body: []byte(`{ + "value": { + "bar": "hi" + } + }`), + ExpectResult: &PostUnionWithJsonNameOutput{ + Value: &types.UnionWithJsonNameMemberBar{Value: "hi"}, + }, + }, + } + for name, c := range cases { + t.Run(name, func(t *testing.T) { + serverURL := "http://localhost:8888/" + client := New(Options{ + HTTPClient: smithyhttp.ClientDoFunc(func(r *http.Request) (*http.Response, error) { + headers := http.Header{} + for k, vs := range c.Header { + for _, v := range vs { + headers.Add(k, v) + } + } + if len(c.BodyMediaType) != 0 && len(headers.Values("Content-Type")) == 0 { + headers.Set("Content-Type", c.BodyMediaType) + } + response := &http.Response{ + StatusCode: c.StatusCode, + Header: headers, + Request: r, + } + if len(c.Body) != 0 { + response.ContentLength = int64(len(c.Body)) + response.Body = ioutil.NopCloser(bytes.NewReader(c.Body)) + } else { + + response.Body = http.NoBody + } + return response, nil + }), + APIOptions: []func(*middleware.Stack) error{ + func(s *middleware.Stack) error { + s.Finalize.Clear() + s.Initialize.Remove(`OperationInputValidation`) + return nil + }, + }, + EndpointResolver: EndpointResolverFunc(func(region string, options EndpointResolverOptions) (e aws.Endpoint, err error) { + e.URL = serverURL + e.SigningRegion = "us-west-2" + return e, err + }), + IdempotencyTokenProvider: smithyrand.NewUUIDIdempotencyToken(&smithytesting.ByteLoop{}), + Region: "us-west-2", + }) + var params PostUnionWithJsonNameInput + result, err := client.PostUnionWithJsonName(context.Background(), ¶ms) + if err != nil { + t.Fatalf("expect nil err, got %v", err) + } + if result == nil { + t.Fatalf("expect not nil result") + } + opts := cmp.Options{ + cmpopts.IgnoreUnexported( + middleware.Metadata{}, + ), + cmp.FilterValues(func(x, y float64) bool { + return math.IsNaN(x) && math.IsNaN(y) + }, cmp.Comparer(func(_, _ interface{}) bool { return true })), + cmp.FilterValues(func(x, y float32) bool { + return math.IsNaN(float64(x)) && math.IsNaN(float64(y)) + }, cmp.Comparer(func(_, _ interface{}) bool { return true })), + cmpopts.IgnoreTypes(smithydocument.NoSerde{}), + } + if err := smithytesting.CompareValues(c.ExpectResult, result, opts...); err != nil { + t.Errorf("expect c.ExpectResult value match:\n%v", err) + } + }) + } +} diff --git a/internal/protocoltest/awsrestjson/deserializers.go b/internal/protocoltest/awsrestjson/deserializers.go index c50aa004c5a..b61d403564f 100644 --- a/internal/protocoltest/awsrestjson/deserializers.go +++ b/internal/protocoltest/awsrestjson/deserializers.go @@ -4168,10 +4168,9 @@ func (m *awsRestjson1_deserializeOpMalformedAcceptWithGenericString) HandleDeser output := &MalformedAcceptWithGenericStringOutput{} out.Result = output - if _, err = io.Copy(ioutil.Discard, response.Body); err != nil { - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to discard response body, %w", err), - } + err = awsRestjson1_deserializeOpDocumentMalformedAcceptWithGenericStringOutput(output, response.Body, response.ContentLength) + if err != nil { + return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("failed to deserialize response payload, %w", err)} } return out, metadata, err @@ -4228,6 +4227,28 @@ func awsRestjson1_deserializeOpErrorMalformedAcceptWithGenericString(response *s } } +func awsRestjson1_deserializeOpDocumentMalformedAcceptWithGenericStringOutput(v *MalformedAcceptWithGenericStringOutput, body io.ReadCloser, contentLength int64) error { + if v == nil { + return fmt.Errorf("unsupported deserialization of nil %T", v) + } + + var buf bytes.Buffer + if contentLength > 0 { + buf.Grow(int(contentLength)) + } else { + buf.Grow(512) + } + + _, err := buf.ReadFrom(body) + if err != nil { + return err + } + if buf.Len() > 0 { + v.Payload = ptr.String(buf.String()) + } + return nil +} + type awsRestjson1_deserializeOpMalformedAcceptWithPayload struct { } @@ -5539,92 +5560,6 @@ func awsRestjson1_deserializeOpErrorMalformedRequestBody(response *smithyhttp.Re } } -type awsRestjson1_deserializeOpMalformedSet struct { -} - -func (*awsRestjson1_deserializeOpMalformedSet) ID() string { - return "OperationDeserializer" -} - -func (m *awsRestjson1_deserializeOpMalformedSet) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsRestjson1_deserializeOpErrorMalformedSet(response, &metadata) - } - output := &MalformedSetOutput{} - out.Result = output - - if _, err = io.Copy(ioutil.Discard, response.Body); err != nil { - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to discard response body, %w", err), - } - } - - return out, metadata, err -} - -func awsRestjson1_deserializeOpErrorMalformedSet(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - type awsRestjson1_deserializeOpMalformedShort struct { } @@ -7651,6 +7586,150 @@ func awsRestjson1_deserializeOpDocumentPostPlayerActionOutput(v **PostPlayerActi return nil } +type awsRestjson1_deserializeOpPostUnionWithJsonName struct { +} + +func (*awsRestjson1_deserializeOpPostUnionWithJsonName) ID() string { + return "OperationDeserializer" +} + +func (m *awsRestjson1_deserializeOpPostUnionWithJsonName) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( + out middleware.DeserializeOutput, metadata middleware.Metadata, err error, +) { + out, metadata, err = next.HandleDeserialize(ctx, in) + if err != nil { + return out, metadata, err + } + + response, ok := out.RawResponse.(*smithyhttp.Response) + if !ok { + return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} + } + + if response.StatusCode < 200 || response.StatusCode >= 300 { + return out, metadata, awsRestjson1_deserializeOpErrorPostUnionWithJsonName(response, &metadata) + } + output := &PostUnionWithJsonNameOutput{} + out.Result = output + + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(response.Body, ringBuffer) + + decoder := json.NewDecoder(body) + decoder.UseNumber() + var shape interface{} + if err := decoder.Decode(&shape); err != nil && err != io.EOF { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return out, metadata, err + } + + err = awsRestjson1_deserializeOpDocumentPostUnionWithJsonNameOutput(&output, shape) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return out, metadata, &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body with invalid JSON, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + return out, metadata, err +} + +func awsRestjson1_deserializeOpErrorPostUnionWithJsonName(response *smithyhttp.Response, metadata *middleware.Metadata) error { + var errorBuffer bytes.Buffer + if _, err := io.Copy(&errorBuffer, response.Body); err != nil { + return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} + } + errorBody := bytes.NewReader(errorBuffer.Bytes()) + + errorCode := "UnknownError" + errorMessage := errorCode + + code := response.Header.Get("X-Amzn-ErrorType") + if len(code) != 0 { + errorCode = restjson.SanitizeErrorCode(code) + } + + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(errorBody, ringBuffer) + decoder := json.NewDecoder(body) + decoder.UseNumber() + code, message, err := restjson.GetErrorInfo(decoder) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + errorBody.Seek(0, io.SeekStart) + if len(code) != 0 { + errorCode = restjson.SanitizeErrorCode(code) + } + if len(message) != 0 { + errorMessage = message + } + + switch { + default: + genericError := &smithy.GenericAPIError{ + Code: errorCode, + Message: errorMessage, + } + return genericError + + } +} + +func awsRestjson1_deserializeOpDocumentPostUnionWithJsonNameOutput(v **PostUnionWithJsonNameOutput, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *PostUnionWithJsonNameOutput + if *v == nil { + sv = &PostUnionWithJsonNameOutput{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "value": + if err := awsRestjson1_deserializeDocumentUnionWithJsonName(&sv.Value, value); err != nil { + return err + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + type awsRestjson1_deserializeOpQueryIdempotencyTokenAutoFill struct { } @@ -10546,6 +10625,72 @@ func awsRestjson1_deserializeDocumentTestConfig(v **types.TestConfig, value inte return nil } +func awsRestjson1_deserializeDocumentUnionWithJsonName(v *types.UnionWithJsonName, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var uv types.UnionWithJsonName +loop: + for key, value := range shape { + if value == nil { + continue + } + switch key { + case "bar": + var mv string + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected String to be of type string, got %T instead", value) + } + mv = jtv + } + uv = &types.UnionWithJsonNameMemberBar{Value: mv} + break loop + + case "_baz": + var mv string + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected String to be of type string, got %T instead", value) + } + mv = jtv + } + uv = &types.UnionWithJsonNameMemberBaz{Value: mv} + break loop + + case "FOO": + var mv string + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected String to be of type string, got %T instead", value) + } + mv = jtv + } + uv = &types.UnionWithJsonNameMemberFoo{Value: mv} + break loop + + default: + uv = &types.UnknownUnionMember{Tag: key} + break loop + + } + } + *v = uv + return nil +} + func awsRestjson1_deserializeDocumentRenamedGreeting(v **types.RenamedGreeting, value interface{}) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) @@ -10611,7 +10756,7 @@ func awsRestjson1_deserializeDocumentBooleanList(v *[]bool, value interface{}) e if value != nil { jtv, ok := value.(bool) if !ok { - return fmt.Errorf("expected PrimitiveBoolean to be of type *bool, got %T instead", value) + return fmt.Errorf("expected Boolean to be of type *bool, got %T instead", value) } col = jtv } diff --git a/internal/protocoltest/awsrestjson/generated.json b/internal/protocoltest/awsrestjson/generated.json index 0f3c28c3522..1b63c91cc63 100644 --- a/internal/protocoltest/awsrestjson/generated.json +++ b/internal/protocoltest/awsrestjson/generated.json @@ -90,7 +90,6 @@ "api_op_MalformedLong.go", "api_op_MalformedMap.go", "api_op_MalformedRequestBody.go", - "api_op_MalformedSet.go", "api_op_MalformedShort.go", "api_op_MalformedString.go", "api_op_MalformedTimestampBodyDateTime.go", @@ -119,6 +118,8 @@ "api_op_OmitsNullSerializesEmptyString_test.go", "api_op_PostPlayerAction.go", "api_op_PostPlayerAction_test.go", + "api_op_PostUnionWithJsonName.go", + "api_op_PostUnionWithJsonName_test.go", "api_op_QueryIdempotencyTokenAutoFill.go", "api_op_QueryIdempotencyTokenAutoFill_test.go", "api_op_QueryParamsAsStringListMap.go", diff --git a/internal/protocoltest/awsrestjson/serializers.go b/internal/protocoltest/awsrestjson/serializers.go index ceb6bce2e10..f05338439be 100644 --- a/internal/protocoltest/awsrestjson/serializers.go +++ b/internal/protocoltest/awsrestjson/serializers.go @@ -2499,18 +2499,6 @@ func (m *awsRestjson1_serializeOpMalformedAcceptWithGenericString) HandleSeriali return out, metadata, &smithy.SerializationError{Err: err} } - if !restEncoder.HasHeader("Content-Type") { - ctx = smithyhttp.SetIsContentTypeDefaultValue(ctx, true) - restEncoder.SetHeader("Content-Type").String("application/octet-stream") - } - - if input.Payload != nil { - payload := bytes.NewReader(input.Payload) - if request, err = request.SetStream(payload); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - } - if request.Request, err = restEncoder.Encode(request.Request); err != nil { return out, metadata, &smithy.SerializationError{Err: err} } @@ -3658,83 +3646,6 @@ func awsRestjson1_serializeOpDocumentMalformedRequestBodyInput(v *MalformedReque return nil } -type awsRestjson1_serializeOpMalformedSet struct { -} - -func (*awsRestjson1_serializeOpMalformedSet) ID() string { - return "OperationSerializer" -} - -func (m *awsRestjson1_serializeOpMalformedSet) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*MalformedSetInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - opPath, opQuery := httpbinding.SplitURI("/MalformedSet") - request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) - request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) - request.Method = "POST" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - restEncoder.SetHeader("Content-Type").String("application/json") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsRestjson1_serializeOpDocumentMalformedSetInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = restEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} -func awsRestjson1_serializeOpHttpBindingsMalformedSetInput(v *MalformedSetInput, encoder *httpbinding.Encoder) error { - if v == nil { - return fmt.Errorf("unsupported serialization of nil %T", v) - } - - return nil -} - -func awsRestjson1_serializeOpDocumentMalformedSetInput(v *MalformedSetInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.BlobSet != nil { - ok := object.Key("blobSet") - if err := awsRestjson1_serializeDocumentBlobSet(v.BlobSet, ok); err != nil { - return err - } - } - - if v.Set != nil { - ok := object.Key("set") - if err := awsRestjson1_serializeDocumentSimpleSet(v.Set, ok); err != nil { - return err - } - } - - return nil -} - type awsRestjson1_serializeOpMalformedShort struct { } @@ -5069,6 +4980,76 @@ func awsRestjson1_serializeOpDocumentPostPlayerActionInput(v *PostPlayerActionIn return nil } +type awsRestjson1_serializeOpPostUnionWithJsonName struct { +} + +func (*awsRestjson1_serializeOpPostUnionWithJsonName) ID() string { + return "OperationSerializer" +} + +func (m *awsRestjson1_serializeOpPostUnionWithJsonName) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( + out middleware.SerializeOutput, metadata middleware.Metadata, err error, +) { + request, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} + } + + input, ok := in.Parameters.(*PostUnionWithJsonNameInput) + _ = input + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} + } + + opPath, opQuery := httpbinding.SplitURI("/PostUnionWithJsonName") + request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) + request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) + request.Method = "POST" + restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + if err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + restEncoder.SetHeader("Content-Type").String("application/json") + + jsonEncoder := smithyjson.NewEncoder() + if err := awsRestjson1_serializeOpDocumentPostUnionWithJsonNameInput(input, jsonEncoder.Value); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request.Request, err = restEncoder.Encode(request.Request); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + in.Request = request + + return next.HandleSerialize(ctx, in) +} +func awsRestjson1_serializeOpHttpBindingsPostUnionWithJsonNameInput(v *PostUnionWithJsonNameInput, encoder *httpbinding.Encoder) error { + if v == nil { + return fmt.Errorf("unsupported serialization of nil %T", v) + } + + return nil +} + +func awsRestjson1_serializeOpDocumentPostUnionWithJsonNameInput(v *PostUnionWithJsonNameInput, value smithyjson.Value) error { + object := value.Object() + defer object.Close() + + if v.Value != nil { + ok := object.Key("value") + if err := awsRestjson1_serializeDocumentUnionWithJsonName(v.Value, ok); err != nil { + return err + } + } + + return nil +} + type awsRestjson1_serializeOpQueryIdempotencyTokenAutoFill struct { } @@ -6065,20 +6046,6 @@ func awsRestjson1_serializeOpHttpBindingsUnitInputAndOutputInput(v *UnitInputAnd return nil } -func awsRestjson1_serializeDocumentBlobSet(v [][]byte, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if vv := v[i]; vv == nil { - continue - } - av.Base64EncodeBytes(v[i]) - } - return nil -} - func awsRestjson1_serializeDocumentDenseBooleanMap(v map[string]bool, value smithyjson.Value) error { object := value.Object() defer object.Close() @@ -6324,17 +6291,6 @@ func awsRestjson1_serializeDocumentSimpleMap(v map[string]string, value smithyjs return nil } -func awsRestjson1_serializeDocumentSimpleSet(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - func awsRestjson1_serializeDocumentSimpleUnion(v types.SimpleUnion, value smithyjson.Value) error { object := value.Object() defer object.Close() @@ -6461,6 +6417,30 @@ func awsRestjson1_serializeDocumentTestConfig(v *types.TestConfig, value smithyj return nil } +func awsRestjson1_serializeDocumentUnionWithJsonName(v types.UnionWithJsonName, value smithyjson.Value) error { + object := value.Object() + defer object.Close() + + switch uv := v.(type) { + case *types.UnionWithJsonNameMemberBar: + av := object.Key("bar") + av.String(uv.Value) + + case *types.UnionWithJsonNameMemberBaz: + av := object.Key("_baz") + av.String(uv.Value) + + case *types.UnionWithJsonNameMemberFoo: + av := object.Key("FOO") + av.String(uv.Value) + + default: + return fmt.Errorf("attempted to serialize unknown member type %T for union %T", uv, v) + + } + return nil +} + func awsRestjson1_serializeDocumentRenamedGreeting(v *types.RenamedGreeting, value smithyjson.Value) error { object := value.Object() defer object.Close() diff --git a/internal/protocoltest/awsrestjson/types/types.go b/internal/protocoltest/awsrestjson/types/types.go index 7f0c939ee9a..3961fab1b41 100644 --- a/internal/protocoltest/awsrestjson/types/types.go +++ b/internal/protocoltest/awsrestjson/types/types.go @@ -195,6 +195,39 @@ type TestConfig struct { noSmithyDocumentSerde } +// The following types satisfy this interface: +// +// UnionWithJsonNameMemberBar +// UnionWithJsonNameMemberBaz +// UnionWithJsonNameMemberFoo +type UnionWithJsonName interface { + isUnionWithJsonName() +} + +type UnionWithJsonNameMemberBar struct { + Value string + + noSmithyDocumentSerde +} + +func (*UnionWithJsonNameMemberBar) isUnionWithJsonName() {} + +type UnionWithJsonNameMemberBaz struct { + Value string + + noSmithyDocumentSerde +} + +func (*UnionWithJsonNameMemberBaz) isUnionWithJsonName() {} + +type UnionWithJsonNameMemberFoo struct { + Value string + + noSmithyDocumentSerde +} + +func (*UnionWithJsonNameMemberFoo) isUnionWithJsonName() {} + type RenamedGreeting struct { Salutation *string @@ -222,6 +255,7 @@ type UnknownUnionMember struct { noSmithyDocumentSerde } -func (*UnknownUnionMember) isMyUnion() {} -func (*UnknownUnionMember) isPlayerAction() {} -func (*UnknownUnionMember) isSimpleUnion() {} +func (*UnknownUnionMember) isMyUnion() {} +func (*UnknownUnionMember) isPlayerAction() {} +func (*UnknownUnionMember) isSimpleUnion() {} +func (*UnknownUnionMember) isUnionWithJsonName() {} diff --git a/internal/protocoltest/awsrestjson/types/types_exported_test.go b/internal/protocoltest/awsrestjson/types/types_exported_test.go index aef17b95e78..002794e3361 100644 --- a/internal/protocoltest/awsrestjson/types/types_exported_test.go +++ b/internal/protocoltest/awsrestjson/types/types_exported_test.go @@ -101,3 +101,27 @@ func ExampleSimpleUnion_outputUsage() { var _ *string var _ *int32 + +func ExampleUnionWithJsonName_outputUsage() { + var union types.UnionWithJsonName + // type switches can be used to check the union value + switch v := union.(type) { + case *types.UnionWithJsonNameMemberBar: + _ = v.Value // Value is string + + case *types.UnionWithJsonNameMemberBaz: + _ = v.Value // Value is string + + case *types.UnionWithJsonNameMemberFoo: + _ = v.Value // Value is string + + case *types.UnknownUnionMember: + fmt.Println("unknown tag:", v.Tag) + + default: + fmt.Println("union is nil or unknown type") + + } +} + +var _ *string diff --git a/internal/protocoltest/ec2query/deserializers.go b/internal/protocoltest/ec2query/deserializers.go index 663b54b99d8..cc9dd18902f 100644 --- a/internal/protocoltest/ec2query/deserializers.go +++ b/internal/protocoltest/ec2query/deserializers.go @@ -2671,7 +2671,7 @@ func awsEc2query_deserializeDocumentBooleanList(v *[]bool, decoder smithyxml.Nod { xtv, err := strconv.ParseBool(string(val)) if err != nil { - return fmt.Errorf("expected PrimitiveBoolean to be of type *bool, got %T instead", val) + return fmt.Errorf("expected Boolean to be of type *bool, got %T instead", val) } col = xtv } @@ -2713,7 +2713,7 @@ func awsEc2query_deserializeDocumentBooleanListUnwrapped(v *[]bool, decoder smit { xtv, err := strconv.ParseBool(string(val)) if err != nil { - return fmt.Errorf("expected PrimitiveBoolean to be of type *bool, got %T instead", val) + return fmt.Errorf("expected Boolean to be of type *bool, got %T instead", val) } mv = xtv } diff --git a/internal/protocoltest/query/deserializers.go b/internal/protocoltest/query/deserializers.go index b276712e5f7..5b075597335 100644 --- a/internal/protocoltest/query/deserializers.go +++ b/internal/protocoltest/query/deserializers.go @@ -4097,7 +4097,7 @@ func awsAwsquery_deserializeDocumentBooleanList(v *[]bool, decoder smithyxml.Nod { xtv, err := strconv.ParseBool(string(val)) if err != nil { - return fmt.Errorf("expected PrimitiveBoolean to be of type *bool, got %T instead", val) + return fmt.Errorf("expected Boolean to be of type *bool, got %T instead", val) } col = xtv } @@ -4139,7 +4139,7 @@ func awsAwsquery_deserializeDocumentBooleanListUnwrapped(v *[]bool, decoder smit { xtv, err := strconv.ParseBool(string(val)) if err != nil { - return fmt.Errorf("expected PrimitiveBoolean to be of type *bool, got %T instead", val) + return fmt.Errorf("expected Boolean to be of type *bool, got %T instead", val) } mv = xtv } diff --git a/internal/protocoltest/restxml/deserializers.go b/internal/protocoltest/restxml/deserializers.go index 27051d15e4a..4a8cc0e147e 100644 --- a/internal/protocoltest/restxml/deserializers.go +++ b/internal/protocoltest/restxml/deserializers.go @@ -8446,7 +8446,7 @@ func awsRestxml_deserializeDocumentBooleanList(v *[]bool, decoder smithyxml.Node { xtv, err := strconv.ParseBool(string(val)) if err != nil { - return fmt.Errorf("expected PrimitiveBoolean to be of type *bool, got %T instead", val) + return fmt.Errorf("expected Boolean to be of type *bool, got %T instead", val) } col = xtv } @@ -8488,7 +8488,7 @@ func awsRestxml_deserializeDocumentBooleanListUnwrapped(v *[]bool, decoder smith { xtv, err := strconv.ParseBool(string(val)) if err != nil { - return fmt.Errorf("expected PrimitiveBoolean to be of type *bool, got %T instead", val) + return fmt.Errorf("expected Boolean to be of type *bool, got %T instead", val) } mv = xtv }