Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,55 +39,46 @@ abstract class MemberShapeDecodeXMLGenerator(
abstract fun renderAssigningDecodedMember(memberName: String, decodedMemberName: String, isBoxed: Boolean = false)
abstract fun renderAssigningSymbol(memberName: String, symbol: String)
abstract fun renderAssigningNil(memberName: String)
abstract fun renderListMember(member: MemberShape, memberTarget: CollectionShape, containerName: String)
abstract fun renderMapMember(member: MemberShape, memberTarget: MapShape, containerName: String)

fun renderListMember(
member: MemberShape,
memberTarget: CollectionShape,
containerName: String
) {
val memberName = ctx.symbolProvider.toMemberName(member).removeSurrounding("`", "`")
fun renderListMember(memberName: String, containerName: String, member: MemberShape, memberTarget: CollectionShape) {
val memberIsFlattened = member.hasTrait(XmlFlattenedTrait::class.java)
var currContainerName = containerName
var currContainerKey = ".$memberName"
var containerUsedForDecoding: String
var ifNilOrIfLetStatement: String
val nextContainerName = "${memberName}WrappedContainer"
if (!memberIsFlattened) {
val memberCodingKey = CollectionMemberCodingKey.construct(memberTarget.member)
memberCodingKey.renderStructs(writer)
writer.write("let $nextContainerName = $currContainerName.nestedContainerNonThrowable(keyedBy: CollectionMemberCodingKey<${memberCodingKey.keyTag()}>.CodingKeys.self, forKey: $currContainerKey)")
currContainerKey = ".member"
currContainerName = nextContainerName
containerUsedForDecoding = currContainerName
ifNilOrIfLetStatement = "if let $currContainerName = $currContainerName {"
} else {
writer.write("let $nextContainerName = $currContainerName.nestedContainerNonThrowable(keyedBy: CodingKeys.self, forKey: $currContainerKey)")
// currContainerKey is intentionally not updated. This container is only used to detect empty lists, not for decoding.
currContainerName = nextContainerName
containerUsedForDecoding = containerName
ifNilOrIfLetStatement = "if $currContainerName != nil {"
}

writer.openBlock("if $containerName.contains(.$memberName) {", "} else {") {
var containerUsedForDecoding: String
var ifNilOrIfLetStatement: String
val nextContainerName = "${memberName}WrappedContainer"
if (!memberIsFlattened) {
val memberCodingKey = CollectionMemberCodingKey.construct(memberTarget.member)
memberCodingKey.renderStructs(writer)
writer.write("let $nextContainerName = $currContainerName.nestedContainerNonThrowable(keyedBy: CollectionMemberCodingKey<${memberCodingKey.keyTag()}>.CodingKeys.self, forKey: $currContainerKey)")
currContainerKey = ".member"
currContainerName = nextContainerName
containerUsedForDecoding = currContainerName
ifNilOrIfLetStatement = "if let $currContainerName = $currContainerName {"
} else {
writer.write("let $nextContainerName = $currContainerName.nestedContainerNonThrowable(keyedBy: CodingKeys.self, forKey: $currContainerKey)")
// currContainerKey is intentionally not updated. This container is only used to detect empty lists, not for decoding.
currContainerName = nextContainerName
containerUsedForDecoding = containerName
ifNilOrIfLetStatement = "if $currContainerName != nil {"
}

writer.openBlock(ifNilOrIfLetStatement, "} else {") {
val memberBuffer = "${memberName}Buffer"
val memberContainerName = "${memberName}Container"
val (memberTargetSymbol, memberTargetSymbolName) = nestedMemberTargetSymbolMapper(memberTarget)
writer.write("let $memberContainerName = try $containerUsedForDecoding.decodeIfPresent($memberTargetSymbolName.self, forKey: $currContainerKey)")
writer.write("var $memberBuffer:\$T = nil", memberTargetSymbol)
writer.openBlock("if let $memberContainerName = $memberContainerName {", "}") {
writer.write("$memberBuffer = \$N()", memberTargetSymbol)
renderListMemberItems(memberTarget, memberContainerName, memberBuffer)
}
renderAssigningDecodedMember(memberName, memberBuffer)
writer.openBlock(ifNilOrIfLetStatement, "} else {") {
val memberBuffer = "${memberName}Buffer"
val memberContainerName = "${memberName}Container"
val (memberTargetSymbol, memberTargetSymbolName) = nestedMemberTargetSymbolMapper(memberTarget)
writer.write("let $memberContainerName = try $containerUsedForDecoding.decodeIfPresent($memberTargetSymbolName.self, forKey: $currContainerKey)")
writer.write("var $memberBuffer:\$T = nil", memberTargetSymbol)
writer.openBlock("if let $memberContainerName = $memberContainerName {", "}") {
writer.write("$memberBuffer = \$N()", memberTargetSymbol)
renderListMemberItems(memberTarget, memberContainerName, memberBuffer)
}
writer.indent()
renderAssigningSymbol(memberName, "[]")
writer.dedent().write("}")
renderAssigningDecodedMember(memberName, memberBuffer)
}
writer.indent()
renderAssigningNil(memberName)
renderAssigningSymbol(memberName, "[]")
writer.dedent().write("}")
}

Expand Down Expand Up @@ -157,53 +148,47 @@ abstract class MemberShapeDecodeXMLGenerator(
}
}

fun renderMapMember(member: MemberShape, memberTarget: MapShape, containerName: String) {
fun renderMapMember(member: MemberShape, memberTarget: MapShape, containerName: String, memberName: String) {
val memberTargetValue = ctx.symbolProvider.toSymbol(memberTarget.value)
val symbolOptional = if (ctx.symbolProvider.toSymbol(memberTarget).isBoxed()) "?" else ""

val memberName = ctx.symbolProvider.toMemberName(member)
val memberNameUnquoted = memberName.removeSurrounding("`", "`")
var currContainerName = containerName
var currContainerKey = ".$memberNameUnquoted"
val memberIsFlattened = member.hasTrait<XmlFlattenedTrait>()
writer.openBlock("if $containerName.contains(.$memberName) {", "} else {") {
val keyedBySymbolForContainer = determineSymbolForShapeInMap(memberTarget, ClientRuntimeTypes.Serde.MapEntry, true)
var containerUsedForDecoding: String
var ifNilOrIfLetStatement: String
val nextContainerName = "${memberNameUnquoted}WrappedContainer"
writer.write("let $nextContainerName = $currContainerName.nestedContainerNonThrowable(keyedBy: $keyedBySymbolForContainer.CodingKeys.self, forKey: $currContainerKey)")
if (!memberIsFlattened) {
currContainerKey = ".entry"
currContainerName = nextContainerName
containerUsedForDecoding = currContainerName
ifNilOrIfLetStatement = "if let $currContainerName = $currContainerName {"
} else {
// currContainerKey is intentionally not updated. This container is only used to detect empty lists, not for decoding.
currContainerName = nextContainerName
containerUsedForDecoding = containerName
ifNilOrIfLetStatement = "if $currContainerName != nil {"
}
val keyedBySymbolForContainer = determineSymbolForShapeInMap(memberTarget, ClientRuntimeTypes.Serde.MapEntry, true)
var containerUsedForDecoding: String
var ifNilOrIfLetStatement: String
val nextContainerName = "${memberNameUnquoted}WrappedContainer"
writer.write("let $nextContainerName = $currContainerName.nestedContainerNonThrowable(keyedBy: $keyedBySymbolForContainer.CodingKeys.self, forKey: $currContainerKey)")
if (!memberIsFlattened) {
currContainerKey = ".entry"
currContainerName = nextContainerName
containerUsedForDecoding = currContainerName
ifNilOrIfLetStatement = "if let $currContainerName = $currContainerName {"
} else {
// currContainerKey is intentionally not updated. This container is only used to detect empty lists, not for decoding.
currContainerName = nextContainerName
containerUsedForDecoding = containerName
ifNilOrIfLetStatement = "if $currContainerName != nil {"
}

writer.openBlock(ifNilOrIfLetStatement, "} else {") {
val memberBuffer = "${memberNameUnquoted}Buffer"
val memberContainerName = "${memberNameUnquoted}Container"
val memberTargetSymbol = "[${SwiftTypes.String}:$memberTargetValue]"
writer.openBlock(ifNilOrIfLetStatement, "} else {") {
val memberBuffer = "${memberNameUnquoted}Buffer"
val memberContainerName = "${memberNameUnquoted}Container"
val memberTargetSymbol = "[${SwiftTypes.String}:$memberTargetValue]"

val symbolToDecodeTo = determineSymbolForShapeInMap(memberTarget, ClientRuntimeTypes.Serde.MapKeyValue, false)
writer.write("let $memberContainerName = try $containerUsedForDecoding.decodeIfPresent([$symbolToDecodeTo].self, forKey: $currContainerKey)")
writer.write("var $memberBuffer: ${memberTargetSymbol}$symbolOptional = nil")
writer.openBlock("if let $memberContainerName = $memberContainerName {", "}") {
writer.write("$memberBuffer = $memberTargetSymbol()")
renderMapMemberItems(memberTarget.value, memberContainerName, memberBuffer)
}
renderAssigningDecodedMember(memberName, memberBuffer)
val symbolToDecodeTo = determineSymbolForShapeInMap(memberTarget, ClientRuntimeTypes.Serde.MapKeyValue, false)
writer.write("let $memberContainerName = try $containerUsedForDecoding.decodeIfPresent([$symbolToDecodeTo].self, forKey: $currContainerKey)")
writer.write("var $memberBuffer: ${memberTargetSymbol}$symbolOptional = nil")
writer.openBlock("if let $memberContainerName = $memberContainerName {", "}") {
writer.write("$memberBuffer = $memberTargetSymbol()")
renderMapMemberItems(memberTarget.value, memberContainerName, memberBuffer)
}
writer.indent()
renderAssigningSymbol(memberName, "[:]")
writer.dedent().write("}")
renderAssigningDecodedMember(memberName, memberBuffer)
}
writer.indent()
renderAssigningNil(memberName)
renderAssigningSymbol(memberName, "[:]")
writer.dedent().write("}")
}

Expand Down Expand Up @@ -249,7 +234,7 @@ abstract class MemberShapeDecodeXMLGenerator(
}
}

fun renderTimestampMember(member: MemberShape, memberTarget: TimestampShape, containerName: String) {
open fun renderTimestampMember(member: MemberShape, memberTarget: TimestampShape, containerName: String) {
val memberName = ctx.symbolProvider.toMemberName(member).removeSurrounding("`", "`")
var memberTargetSymbol = ctx.symbolProvider.toSymbol(memberTarget)
val decodeVerb = if (memberTargetSymbol.isBoxed()) "decodeIfPresent" else "decode"
Expand All @@ -265,14 +250,15 @@ abstract class MemberShapeDecodeXMLGenerator(
renderAssigningDecodedMember(memberName, memberBuffer)
}

fun renderBlobMember(member: MemberShape, memberTarget: BlobShape, containerName: String) {
open fun renderBlobMember(member: MemberShape, memberTarget: BlobShape, containerName: String) {
val memberName = ctx.symbolProvider.toMemberName(member)
val memberNameUnquoted = memberName.removeSurrounding("`", "`")
var memberTargetSymbol = ctx.symbolProvider.toSymbol(memberTarget)
if (member.hasTrait(SwiftBoxTrait::class.java)) {
memberTargetSymbol = memberTargetSymbol.recursiveSymbol()
}
val decodedMemberName = "${memberName}Decoded"

writer.openBlock("if $containerName.contains(.$memberNameUnquoted) {", "} else {") {
writer.openBlock("do {", "} catch {") {
writer.write("let $decodedMemberName = try $containerName.decodeIfPresent(\$N.self, forKey: .$memberNameUnquoted)", memberTargetSymbol)
Expand All @@ -293,14 +279,14 @@ abstract class MemberShapeDecodeXMLGenerator(
renderAssigningDecodedMember(memberName, "$value")
}

fun renderScalarMember(member: MemberShape, memberTarget: Shape, containerName: String, unkeyed: Boolean = false) {
fun renderScalarMember(member: MemberShape, memberTarget: Shape, containerName: String, unkeyed: Boolean = false, isUnion: Boolean = false) {
val memberName = ctx.symbolProvider.toMemberName(member)
val memberNameUnquoted = memberName.removeSurrounding("`", "`")
var memberTargetSymbol = ctx.symbolProvider.toSymbol(memberTarget)
if (member.hasTrait(SwiftBoxTrait::class.java)) {
memberTargetSymbol = memberTargetSymbol.recursiveSymbol()
}
val decodeVerb = if (memberTargetSymbol.isBoxed()) "decodeIfPresent" else "decode"
val decodeVerb = if (memberTargetSymbol.isBoxed() && !isUnion) "decodeIfPresent" else "decode"
val decodedMemberName = "${memberNameUnquoted}Decoded"
if (unkeyed) {
writer.write("let $decodedMemberName = try $containerName.$decodeVerb(\$N.self)", memberTargetSymbol)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,26 @@ open class StructDecodeXMLGenerator(
}
}

override fun renderListMember(member: MemberShape, memberTarget: CollectionShape, containerName: String) {
val memberName = ctx.symbolProvider.toMemberName(member).removeSurrounding("`", "`")
writer.openBlock("if $containerName.contains(.$memberName) {", "} else {") {
renderListMember(memberName, containerName, member, memberTarget)
}
writer.indent()
renderAssigningNil(memberName)
writer.dedent().write("}")
}

override fun renderMapMember(member: MemberShape, memberTarget: MapShape, containerName: String) {
val memberName = ctx.symbolProvider.toMemberName(member)
writer.openBlock("if $containerName.contains(.$memberName) {", "} else {") {
renderMapMember(member, memberTarget, containerName, memberName)
}
writer.indent()
renderAssigningNil(memberName)
writer.dedent().write("}")
}

override fun renderAssigningDecodedMember(memberName: String, decodedMemberName: String, isBoxed: Boolean) {
writer.write("$memberName = $decodedMemberName")
}
Expand Down
Loading