@@ -39,55 +39,46 @@ abstract class MemberShapeDecodeXMLGenerator(
3939 abstract fun renderAssigningDecodedMember (memberName : String , decodedMemberName : String , isBoxed : Boolean = false)
4040 abstract fun renderAssigningSymbol (memberName : String , symbol : String )
4141 abstract fun renderAssigningNil (memberName : String )
42+ abstract fun renderListMember (member : MemberShape , memberTarget : CollectionShape , containerName : String )
43+ abstract fun renderMapMember (member : MemberShape , memberTarget : MapShape , containerName : String )
4244
43- fun renderListMember (
44- member : MemberShape ,
45- memberTarget : CollectionShape ,
46- containerName : String
47- ) {
48- val memberName = ctx.symbolProvider.toMemberName(member).removeSurrounding(" `" , " `" )
45+ fun renderListMember (memberName : String , containerName : String , member : MemberShape , memberTarget : CollectionShape ) {
4946 val memberIsFlattened = member.hasTrait(XmlFlattenedTrait ::class .java)
5047 var currContainerName = containerName
5148 var currContainerKey = " .$memberName "
49+ var containerUsedForDecoding: String
50+ var ifNilOrIfLetStatement: String
51+ val nextContainerName = " ${memberName} WrappedContainer"
52+ if (! memberIsFlattened) {
53+ val memberCodingKey = CollectionMemberCodingKey .construct(memberTarget.member)
54+ memberCodingKey.renderStructs(writer)
55+ writer.write(" let $nextContainerName = $currContainerName .nestedContainerNonThrowable(keyedBy: CollectionMemberCodingKey<${memberCodingKey.keyTag()} >.CodingKeys.self, forKey: $currContainerKey )" )
56+ currContainerKey = " .member"
57+ currContainerName = nextContainerName
58+ containerUsedForDecoding = currContainerName
59+ ifNilOrIfLetStatement = " if let $currContainerName = $currContainerName {"
60+ } else {
61+ writer.write(" let $nextContainerName = $currContainerName .nestedContainerNonThrowable(keyedBy: CodingKeys.self, forKey: $currContainerKey )" )
62+ // currContainerKey is intentionally not updated. This container is only used to detect empty lists, not for decoding.
63+ currContainerName = nextContainerName
64+ containerUsedForDecoding = containerName
65+ ifNilOrIfLetStatement = " if $currContainerName != nil {"
66+ }
5267
53- writer.openBlock(" if $containerName .contains(.$memberName ) {" , " } else {" ) {
54- var containerUsedForDecoding: String
55- var ifNilOrIfLetStatement: String
56- val nextContainerName = " ${memberName} WrappedContainer"
57- if (! memberIsFlattened) {
58- val memberCodingKey = CollectionMemberCodingKey .construct(memberTarget.member)
59- memberCodingKey.renderStructs(writer)
60- writer.write(" let $nextContainerName = $currContainerName .nestedContainerNonThrowable(keyedBy: CollectionMemberCodingKey<${memberCodingKey.keyTag()} >.CodingKeys.self, forKey: $currContainerKey )" )
61- currContainerKey = " .member"
62- currContainerName = nextContainerName
63- containerUsedForDecoding = currContainerName
64- ifNilOrIfLetStatement = " if let $currContainerName = $currContainerName {"
65- } else {
66- writer.write(" let $nextContainerName = $currContainerName .nestedContainerNonThrowable(keyedBy: CodingKeys.self, forKey: $currContainerKey )" )
67- // currContainerKey is intentionally not updated. This container is only used to detect empty lists, not for decoding.
68- currContainerName = nextContainerName
69- containerUsedForDecoding = containerName
70- ifNilOrIfLetStatement = " if $currContainerName != nil {"
71- }
72-
73- writer.openBlock(ifNilOrIfLetStatement, " } else {" ) {
74- val memberBuffer = " ${memberName} Buffer"
75- val memberContainerName = " ${memberName} Container"
76- val (memberTargetSymbol, memberTargetSymbolName) = nestedMemberTargetSymbolMapper(memberTarget)
77- writer.write(" let $memberContainerName = try $containerUsedForDecoding .decodeIfPresent($memberTargetSymbolName .self, forKey: $currContainerKey )" )
78- writer.write(" var $memberBuffer :\$ T = nil" , memberTargetSymbol)
79- writer.openBlock(" if let $memberContainerName = $memberContainerName {" , " }" ) {
80- writer.write(" $memberBuffer = \$ N()" , memberTargetSymbol)
81- renderListMemberItems(memberTarget, memberContainerName, memberBuffer)
82- }
83- renderAssigningDecodedMember(memberName, memberBuffer)
68+ writer.openBlock(ifNilOrIfLetStatement, " } else {" ) {
69+ val memberBuffer = " ${memberName} Buffer"
70+ val memberContainerName = " ${memberName} Container"
71+ val (memberTargetSymbol, memberTargetSymbolName) = nestedMemberTargetSymbolMapper(memberTarget)
72+ writer.write(" let $memberContainerName = try $containerUsedForDecoding .decodeIfPresent($memberTargetSymbolName .self, forKey: $currContainerKey )" )
73+ writer.write(" var $memberBuffer :\$ T = nil" , memberTargetSymbol)
74+ writer.openBlock(" if let $memberContainerName = $memberContainerName {" , " }" ) {
75+ writer.write(" $memberBuffer = \$ N()" , memberTargetSymbol)
76+ renderListMemberItems(memberTarget, memberContainerName, memberBuffer)
8477 }
85- writer.indent()
86- renderAssigningSymbol(memberName, " []" )
87- writer.dedent().write(" }" )
78+ renderAssigningDecodedMember(memberName, memberBuffer)
8879 }
8980 writer.indent()
90- renderAssigningNil (memberName)
81+ renderAssigningSymbol (memberName, " [] " )
9182 writer.dedent().write(" }" )
9283 }
9384
@@ -157,53 +148,47 @@ abstract class MemberShapeDecodeXMLGenerator(
157148 }
158149 }
159150
160- fun renderMapMember (member : MemberShape , memberTarget : MapShape , containerName : String ) {
151+ fun renderMapMember (member : MemberShape , memberTarget : MapShape , containerName : String , memberName : String ) {
161152 val memberTargetValue = ctx.symbolProvider.toSymbol(memberTarget.value)
162153 val symbolOptional = if (ctx.symbolProvider.toSymbol(memberTarget).isBoxed()) " ?" else " "
163154
164- val memberName = ctx.symbolProvider.toMemberName(member)
165155 val memberNameUnquoted = memberName.removeSurrounding(" `" , " `" )
166156 var currContainerName = containerName
167157 var currContainerKey = " .$memberNameUnquoted "
168158 val memberIsFlattened = member.hasTrait<XmlFlattenedTrait >()
169- writer.openBlock(" if $containerName .contains(.$memberName ) {" , " } else {" ) {
170- val keyedBySymbolForContainer = determineSymbolForShapeInMap(memberTarget, ClientRuntimeTypes .Serde .MapEntry , true )
171- var containerUsedForDecoding: String
172- var ifNilOrIfLetStatement: String
173- val nextContainerName = " ${memberNameUnquoted} WrappedContainer"
174- writer.write(" let $nextContainerName = $currContainerName .nestedContainerNonThrowable(keyedBy: $keyedBySymbolForContainer .CodingKeys.self, forKey: $currContainerKey )" )
175- if (! memberIsFlattened) {
176- currContainerKey = " .entry"
177- currContainerName = nextContainerName
178- containerUsedForDecoding = currContainerName
179- ifNilOrIfLetStatement = " if let $currContainerName = $currContainerName {"
180- } else {
181- // currContainerKey is intentionally not updated. This container is only used to detect empty lists, not for decoding.
182- currContainerName = nextContainerName
183- containerUsedForDecoding = containerName
184- ifNilOrIfLetStatement = " if $currContainerName != nil {"
185- }
159+ val keyedBySymbolForContainer = determineSymbolForShapeInMap(memberTarget, ClientRuntimeTypes .Serde .MapEntry , true )
160+ var containerUsedForDecoding: String
161+ var ifNilOrIfLetStatement: String
162+ val nextContainerName = " ${memberNameUnquoted} WrappedContainer"
163+ writer.write(" let $nextContainerName = $currContainerName .nestedContainerNonThrowable(keyedBy: $keyedBySymbolForContainer .CodingKeys.self, forKey: $currContainerKey )" )
164+ if (! memberIsFlattened) {
165+ currContainerKey = " .entry"
166+ currContainerName = nextContainerName
167+ containerUsedForDecoding = currContainerName
168+ ifNilOrIfLetStatement = " if let $currContainerName = $currContainerName {"
169+ } else {
170+ // currContainerKey is intentionally not updated. This container is only used to detect empty lists, not for decoding.
171+ currContainerName = nextContainerName
172+ containerUsedForDecoding = containerName
173+ ifNilOrIfLetStatement = " if $currContainerName != nil {"
174+ }
186175
187- writer.openBlock(ifNilOrIfLetStatement, " } else {" ) {
188- val memberBuffer = " ${memberNameUnquoted} Buffer"
189- val memberContainerName = " ${memberNameUnquoted} Container"
190- val memberTargetSymbol = " [${SwiftTypes .String } :$memberTargetValue ]"
176+ writer.openBlock(ifNilOrIfLetStatement, " } else {" ) {
177+ val memberBuffer = " ${memberNameUnquoted} Buffer"
178+ val memberContainerName = " ${memberNameUnquoted} Container"
179+ val memberTargetSymbol = " [${SwiftTypes .String } :$memberTargetValue ]"
191180
192- val symbolToDecodeTo = determineSymbolForShapeInMap(memberTarget, ClientRuntimeTypes .Serde .MapKeyValue , false )
193- writer.write(" let $memberContainerName = try $containerUsedForDecoding .decodeIfPresent([$symbolToDecodeTo ].self, forKey: $currContainerKey )" )
194- writer.write(" var $memberBuffer : ${memberTargetSymbol}$symbolOptional = nil" )
195- writer.openBlock(" if let $memberContainerName = $memberContainerName {" , " }" ) {
196- writer.write(" $memberBuffer = $memberTargetSymbol ()" )
197- renderMapMemberItems(memberTarget.value, memberContainerName, memberBuffer)
198- }
199- renderAssigningDecodedMember(memberName, memberBuffer)
181+ val symbolToDecodeTo = determineSymbolForShapeInMap(memberTarget, ClientRuntimeTypes .Serde .MapKeyValue , false )
182+ writer.write(" let $memberContainerName = try $containerUsedForDecoding .decodeIfPresent([$symbolToDecodeTo ].self, forKey: $currContainerKey )" )
183+ writer.write(" var $memberBuffer : ${memberTargetSymbol}$symbolOptional = nil" )
184+ writer.openBlock(" if let $memberContainerName = $memberContainerName {" , " }" ) {
185+ writer.write(" $memberBuffer = $memberTargetSymbol ()" )
186+ renderMapMemberItems(memberTarget.value, memberContainerName, memberBuffer)
200187 }
201- writer.indent()
202- renderAssigningSymbol(memberName, " [:]" )
203- writer.dedent().write(" }" )
188+ renderAssigningDecodedMember(memberName, memberBuffer)
204189 }
205190 writer.indent()
206- renderAssigningNil (memberName)
191+ renderAssigningSymbol (memberName, " [:] " )
207192 writer.dedent().write(" }" )
208193 }
209194
@@ -249,7 +234,7 @@ abstract class MemberShapeDecodeXMLGenerator(
249234 }
250235 }
251236
252- fun renderTimestampMember (member : MemberShape , memberTarget : TimestampShape , containerName : String ) {
237+ open fun renderTimestampMember (member : MemberShape , memberTarget : TimestampShape , containerName : String ) {
253238 val memberName = ctx.symbolProvider.toMemberName(member).removeSurrounding(" `" , " `" )
254239 var memberTargetSymbol = ctx.symbolProvider.toSymbol(memberTarget)
255240 val decodeVerb = if (memberTargetSymbol.isBoxed()) " decodeIfPresent" else " decode"
@@ -265,14 +250,15 @@ abstract class MemberShapeDecodeXMLGenerator(
265250 renderAssigningDecodedMember(memberName, memberBuffer)
266251 }
267252
268- fun renderBlobMember (member : MemberShape , memberTarget : BlobShape , containerName : String ) {
253+ open fun renderBlobMember (member : MemberShape , memberTarget : BlobShape , containerName : String ) {
269254 val memberName = ctx.symbolProvider.toMemberName(member)
270255 val memberNameUnquoted = memberName.removeSurrounding(" `" , " `" )
271256 var memberTargetSymbol = ctx.symbolProvider.toSymbol(memberTarget)
272257 if (member.hasTrait(SwiftBoxTrait ::class .java)) {
273258 memberTargetSymbol = memberTargetSymbol.recursiveSymbol()
274259 }
275260 val decodedMemberName = " ${memberName} Decoded"
261+
276262 writer.openBlock(" if $containerName .contains(.$memberNameUnquoted ) {" , " } else {" ) {
277263 writer.openBlock(" do {" , " } catch {" ) {
278264 writer.write(" let $decodedMemberName = try $containerName .decodeIfPresent(\$ N.self, forKey: .$memberNameUnquoted )" , memberTargetSymbol)
@@ -293,14 +279,14 @@ abstract class MemberShapeDecodeXMLGenerator(
293279 renderAssigningDecodedMember(memberName, " $value " )
294280 }
295281
296- fun renderScalarMember (member : MemberShape , memberTarget : Shape , containerName : String , unkeyed : Boolean = false) {
282+ fun renderScalarMember (member : MemberShape , memberTarget : Shape , containerName : String , unkeyed : Boolean = false, isUnion : Boolean = false ) {
297283 val memberName = ctx.symbolProvider.toMemberName(member)
298284 val memberNameUnquoted = memberName.removeSurrounding(" `" , " `" )
299285 var memberTargetSymbol = ctx.symbolProvider.toSymbol(memberTarget)
300286 if (member.hasTrait(SwiftBoxTrait ::class .java)) {
301287 memberTargetSymbol = memberTargetSymbol.recursiveSymbol()
302288 }
303- val decodeVerb = if (memberTargetSymbol.isBoxed()) " decodeIfPresent" else " decode"
289+ val decodeVerb = if (memberTargetSymbol.isBoxed() && ! isUnion ) " decodeIfPresent" else " decode"
304290 val decodedMemberName = " ${memberNameUnquoted} Decoded"
305291 if (unkeyed) {
306292 writer.write(" let $decodedMemberName = try $containerName .$decodeVerb (\$ N.self)" , memberTargetSymbol)
0 commit comments