66package aws.sdk.kotlin.codegen.protocols
77
88import aws.sdk.kotlin.codegen.AwsRuntimeTypes
9+ import aws.sdk.kotlin.codegen.protocols.core.AbstractQueryFormUrlSerializerGenerator
910import aws.sdk.kotlin.codegen.protocols.core.AwsHttpBindingProtocolGenerator
1011import aws.sdk.kotlin.codegen.protocols.core.QueryHttpBindingProtocolGenerator
1112import aws.sdk.kotlin.codegen.protocols.formurl.QuerySerdeFormUrlDescriptorGenerator
1213import software.amazon.smithy.aws.traits.protocols.AwsQueryErrorTrait
1314import software.amazon.smithy.aws.traits.protocols.AwsQueryTrait
14- import software.amazon.smithy.kotlin.codegen.core.KotlinWriter
15- import software.amazon.smithy.kotlin.codegen.core.RenderingContext
16- import software.amazon.smithy.kotlin.codegen.core.RuntimeTypes
17- import software.amazon.smithy.kotlin.codegen.core.addImport
15+ import software.amazon.smithy.kotlin.codegen.core.*
1816import software.amazon.smithy.kotlin.codegen.model.*
1917import software.amazon.smithy.kotlin.codegen.model.traits.OperationOutput
2018import software.amazon.smithy.kotlin.codegen.rendering.protocol.*
@@ -32,56 +30,11 @@ import software.amazon.smithy.model.traits.*
3230class AwsQuery : QueryHttpBindingProtocolGenerator () {
3331 override val protocol: ShapeId = AwsQueryTrait .ID
3432
35- override fun getDeserializerDescriptorGenerator (
36- ctx : ProtocolGenerator .GenerationContext ,
37- shape : Shape ,
38- members : List <MemberShape >,
39- writer : KotlinWriter ,
40- ): AbstractSerdeDescriptorGenerator =
41- AwsQuerySerdeXmlDescriptorGenerator (ctx.toRenderingContext(this , shape, writer), members)
33+ override fun structuredDataSerializer (ctx : ProtocolGenerator .GenerationContext ): StructuredDataSerializerGenerator =
34+ AwsQuerySerializerGenerator (this )
4235
43- override fun getSerializerDescriptorGenerator (
44- ctx : ProtocolGenerator .GenerationContext ,
45- shape : Shape ,
46- members : List <MemberShape >,
47- writer : KotlinWriter ,
48- ): AbstractSerdeDescriptorGenerator =
49- AwsQuerySerdeFormUrlDescriptorGenerator (ctx.toRenderingContext(this , shape, writer), members)
50-
51- /* *
52- * Unwraps the response body as specified by
53- * https://awslabs.github.io/smithy/1.0/spec/aws/aws-query-protocol.html#response-serialization so that the
54- * deserializer is in the correct state.
55- */
56- override fun unwrapOperationResponseBody (
57- operationName : String ,
58- writer : KotlinWriter
59- ) {
60- writer
61- .addImport(
62- RuntimeTypes .Serde .SdkFieldDescriptor ,
63- RuntimeTypes .Serde .SerdeXml .XmlSerialName ,
64- RuntimeTypes .Serde .SdkObjectDescriptor ,
65- RuntimeTypes .Serde .deserializeStruct
66- )
67- .write(" " )
68- .write(" val resultDescriptor = #T(SerialKind.Struct, #T(#S))" , RuntimeTypes .Serde .SdkFieldDescriptor , RuntimeTypes .Serde .SerdeXml .XmlSerialName , " ${operationName} Result" )
69- .openBlock(" val wrapperDescriptor = #T.build {" , " }" , RuntimeTypes .Serde .SdkObjectDescriptor ) {
70- writer
71- .addImport(RuntimeTypes .Serde .field)
72- .write(" trait(#T(#S))" , RuntimeTypes .Serde .SerdeXml .XmlSerialName , " ${operationName} Response" )
73- .write(" #T(resultDescriptor)" , RuntimeTypes .Serde .field)
74- }
75- .write(" " )
76- // abandon the iterator, this only occurs at the top level operational output
77- .write(" val wrapper = deserializer.#T(wrapperDescriptor)" , RuntimeTypes .Serde .deserializeStruct)
78- .openBlock(" if (wrapper.findNextFieldIndex() != resultDescriptor.index) {" , " }" ) {
79- writer
80- .addImport(RuntimeTypes .Serde .DeserializationException )
81- .write(" throw #T(#S)" , RuntimeTypes .Serde .DeserializationException , " failed to unwrap $operationName response" )
82- }
83- writer.write(" " )
84- }
36+ override fun structuredDataParser (ctx : ProtocolGenerator .GenerationContext ): StructuredDataParserGenerator =
37+ AwsQueryXmlParserGenerator (this )
8538
8639 override fun getErrorCode (ctx : ProtocolGenerator .GenerationContext , errShapeId : ShapeId ): String {
8740 val errShape = ctx.model.expectShape(errShapeId)
@@ -134,3 +87,63 @@ private class AwsQuerySerdeXmlDescriptorGenerator(
13487 return traits
13588 }
13689}
90+
91+ private class AwsQuerySerializerGenerator (
92+ private val protocolGenerator : AwsQuery
93+ ) : AbstractQueryFormUrlSerializerGenerator(protocolGenerator, protocolGenerator.defaultTimestampFormat) {
94+ override fun descriptorGenerator (
95+ ctx : ProtocolGenerator .GenerationContext ,
96+ shape : Shape ,
97+ members : List <MemberShape >,
98+ writer : KotlinWriter
99+ ): FormUrlSerdeDescriptorGenerator = AwsQuerySerdeFormUrlDescriptorGenerator (ctx.toRenderingContext(protocolGenerator, shape, writer), members)
100+ }
101+
102+ private class AwsQueryXmlParserGenerator (
103+ private val protocolGenerator : AwsQuery
104+ ) : XmlParserGenerator(protocolGenerator, protocolGenerator.defaultTimestampFormat) {
105+
106+ override fun descriptorGenerator (
107+ ctx : ProtocolGenerator .GenerationContext ,
108+ shape : Shape ,
109+ members : List <MemberShape >,
110+ writer : KotlinWriter
111+ ): XmlSerdeDescriptorGenerator = AwsQuerySerdeXmlDescriptorGenerator (ctx.toRenderingContext(protocolGenerator, shape, writer), members)
112+
113+ override fun renderDeserializeOperationBody (
114+ ctx : ProtocolGenerator .GenerationContext ,
115+ op : OperationShape ,
116+ documentMembers : List <MemberShape >,
117+ writer : KotlinWriter
118+ ) {
119+ writer.write(" val deserializer = #T(payload)" , RuntimeTypes .Serde .SerdeXml .XmlDeserializer )
120+ unwrapOperationResponseBody(op.id.name, writer)
121+ val shape = ctx.model.expectShape(op.output.get())
122+ renderDeserializerBody(ctx, shape, documentMembers, writer)
123+ }
124+
125+ /* *
126+ * Unwraps the response body as specified by
127+ * https://awslabs.github.io/smithy/1.0/spec/aws/aws-query-protocol.html#response-serialization so that the
128+ * deserializer is in the correct state.
129+ */
130+ private fun unwrapOperationResponseBody (
131+ operationName : String ,
132+ writer : KotlinWriter
133+ ) {
134+ writer.write(" // begin unwrap response wrapper" )
135+ .write(" val resultDescriptor = #T(#T.Struct, #T(#S))" , RuntimeTypes .Serde .SdkFieldDescriptor , RuntimeTypes .Serde .SerialKind , RuntimeTypes .Serde .SerdeXml .XmlSerialName , " ${operationName} Result" )
136+ .withBlock(" val wrapperDescriptor = #T.build {" , " }" , RuntimeTypes .Serde .SdkObjectDescriptor ) {
137+ write(" trait(#T(#S))" , RuntimeTypes .Serde .SerdeXml .XmlSerialName , " ${operationName} Response" )
138+ write(" #T(resultDescriptor)" , RuntimeTypes .Serde .field)
139+ }
140+ .write(" " )
141+ // abandon the iterator, this only occurs at the top level operational output
142+ .write(" val wrapper = deserializer.#T(wrapperDescriptor)" , RuntimeTypes .Serde .deserializeStruct)
143+ .withBlock(" if (wrapper.findNextFieldIndex() != resultDescriptor.index) {" , " }" ) {
144+ write(" throw #T(#S)" , RuntimeTypes .Serde .DeserializationException , " failed to unwrap $operationName response" )
145+ }
146+ .write(" // end unwrap response wrapper" )
147+ .write(" " )
148+ }
149+ }
0 commit comments