Skip to content

Commit 8f3279a

Browse files
authored
fix: add missing codegen support for Smithy 1.23 upgrade (#691)
1 parent fd3c846 commit 8f3279a

File tree

7 files changed

+117
-72
lines changed

7 files changed

+117
-72
lines changed

runtime/serde/common/src/aws/smithy/kotlin/runtime/serde/SdkFieldDescriptor.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ public sealed class SerialKind {
3333
public object Char : SerialKind()
3434
public object Short : SerialKind()
3535
public object Float : SerialKind()
36+
public object Enum : SerialKind()
37+
public object IntEnum : SerialKind()
3638
public object Map : SerialKind()
3739
public object List : SerialKind()
3840
public object Struct : SerialKind()

smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/model/ShapeExt.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,10 @@ val Shape.isDeprecated: Boolean
154154
* https://awslabs.github.io/smithy/1.0/spec/core/constraint-traits.html#enum-trait
155155
*/
156156
val Shape.isEnum: Boolean
157-
get() = isStringShape && hasTrait<@Suppress("DEPRECATION") software.amazon.smithy.model.traits.EnumTrait>()
157+
get() =
158+
isStringShape && hasTrait<@Suppress("DEPRECATION") software.amazon.smithy.model.traits.EnumTrait>() ||
159+
isEnumShape ||
160+
isIntEnumShape
158161

159162
/**
160163
* Test if a shape is an error.

smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/ShapeValueGenerator.kt

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import software.amazon.smithy.codegen.core.SymbolProvider
99
import software.amazon.smithy.kotlin.codegen.core.*
1010
import software.amazon.smithy.kotlin.codegen.model.SymbolProperty
1111
import software.amazon.smithy.kotlin.codegen.model.hasTrait
12+
import software.amazon.smithy.kotlin.codegen.model.isEnum
1213
import software.amazon.smithy.model.Model
1314
import software.amazon.smithy.model.node.*
1415
import software.amazon.smithy.model.shapes.*
@@ -97,17 +98,14 @@ class ShapeValueGenerator(
9798
RuntimeTypes.Core.Content.StringContent,
9899
RuntimeTypes.Core.Content.toByteArray,
99100
)
100-
val suffix = when (shape.type) {
101-
ShapeType.STRING -> {
102-
if (shape.hasTrait<@Suppress("DEPRECATION") software.amazon.smithy.model.traits.EnumTrait>()) {
103-
val symbol = symbolProvider.toSymbol(shape)
104-
writer.writeInline("#L.fromValue(", symbol.name)
105-
")"
106-
} else {
107-
""
108-
}
101+
val suffix = when {
102+
shape.isEnum -> {
103+
val symbol = symbolProvider.toSymbol(shape)
104+
writer.writeInline("#L.fromValue(", symbol.name)
105+
")"
109106
}
110-
ShapeType.BLOB -> {
107+
108+
shape.type == ShapeType.BLOB -> {
111109
if (shape.hasTrait<StreamingTrait>()) {
112110
writer.addImport(blobHandlingSymbols)
113111
writer.writeInline("StringContent(")
@@ -117,6 +115,7 @@ class ShapeValueGenerator(
117115
".encodeAsByteArray()"
118116
}
119117
}
118+
120119
else -> ""
121120
}
122121

smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpBindingProtocolGenerator.kt

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ abstract class HttpBindingProtocolGenerator : ProtocolGenerator {
437437
writer.write("builder.body = #T(input.#L)", RuntimeTypes.Http.ByteArrayContent, memberName)
438438
}
439439
}
440+
440441
ShapeType.STRING -> {
441442
val contents = if (target.isEnum) {
442443
"$memberName.value"
@@ -445,13 +446,26 @@ abstract class HttpBindingProtocolGenerator : ProtocolGenerator {
445446
}
446447
writer.write("builder.body = #T(input.#L.#T())", RuntimeTypes.Http.ByteArrayContent, contents, KotlinTypes.Text.encodeToByteArray)
447448
}
449+
450+
ShapeType.ENUM ->
451+
writer.write(
452+
"builder.body = #T(input.#L.value.#T())",
453+
RuntimeTypes.Http.ByteArrayContent,
454+
memberName,
455+
KotlinTypes.Text.encodeToByteArray,
456+
)
457+
458+
ShapeType.INT_ENUM -> throw CodegenException("IntEnum is not supported until Smithy 2.0")
459+
448460
ShapeType.STRUCTURE, ShapeType.UNION, ShapeType.DOCUMENT -> {
449461
val sdg = structuredDataSerializer(ctx)
450462
val payloadSerializerFn = sdg.payloadSerializer(ctx, binding.member)
451463
writer.write("val payload = #T(input.#L)", payloadSerializerFn, memberName)
452464
writer.write("builder.body = #T(payload)", RuntimeTypes.Http.ByteArrayContent)
453465
}
454-
else -> throw CodegenException("member shape ${binding.member} serializer not implemented yet")
466+
467+
else ->
468+
throw CodegenException("member shape ${binding.member} (${target.type}) serializer not implemented yet")
455469
}
456470
writer.closeBlock("}")
457471
}
@@ -869,16 +883,21 @@ abstract class HttpBindingProtocolGenerator : ProtocolGenerator {
869883
val targetSymbol = ctx.symbolProvider.toSymbol(target)
870884
when (target.type) {
871885
ShapeType.STRING -> {
872-
writer
873-
.addImport(RuntimeTypes.Http.readAll)
874-
.write("val contents = response.body.#T()?.decodeToString()", RuntimeTypes.Http.readAll)
886+
writer.write("val contents = response.body.#T()?.decodeToString()", RuntimeTypes.Http.readAll)
875887
if (target.isEnum) {
876-
writer.addImport(targetSymbol)
877888
writer.write("builder.$memberName = contents?.let { #T.fromValue(it) }", targetSymbol)
878889
} else {
879890
writer.write("builder.$memberName = contents")
880891
}
881892
}
893+
894+
ShapeType.ENUM -> {
895+
writer.write("val contents = response.body.#T()?.decodeToString()", RuntimeTypes.Http.readAll)
896+
writer.write("builder.#L = contents?.let { #T.fromValue(it) }", memberName, targetSymbol)
897+
}
898+
899+
ShapeType.INT_ENUM -> throw CodegenException("IntEnum is not supported until Smithy 2.0")
900+
882901
ShapeType.BLOB -> {
883902
val isBinaryStream = target.hasTrait<StreamingTrait>()
884903
val conversion = if (isBinaryStream) {
@@ -890,6 +909,7 @@ abstract class HttpBindingProtocolGenerator : ProtocolGenerator {
890909
}
891910
writer.write("builder.$memberName = response.body.$conversion")
892911
}
912+
893913
ShapeType.STRUCTURE, ShapeType.UNION, ShapeType.DOCUMENT -> {
894914
// delegate to the payload deserializer
895915
val sdg = structuredDataParser(ctx)
@@ -900,7 +920,9 @@ abstract class HttpBindingProtocolGenerator : ProtocolGenerator {
900920
write("builder.#L = #T(payload)", memberName, payloadDeserializerFn)
901921
}
902922
}
903-
else -> throw CodegenException("member shape ${binding.member} deserializer not implemented")
923+
924+
else ->
925+
throw CodegenException("member shape ${binding.member} (${target.type}) deserializer not implemented")
904926
}
905927

906928
writer.openBlock("")

smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/serde/DeserializeStructGenerator.kt

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@ package software.amazon.smithy.kotlin.codegen.rendering.serde
66

77
import software.amazon.smithy.codegen.core.CodegenException
88
import software.amazon.smithy.kotlin.codegen.core.*
9-
import software.amazon.smithy.kotlin.codegen.model.SymbolProperty
10-
import software.amazon.smithy.kotlin.codegen.model.hasTrait
11-
import software.amazon.smithy.kotlin.codegen.model.isSparse
12-
import software.amazon.smithy.kotlin.codegen.model.targetOrSelf
9+
import software.amazon.smithy.kotlin.codegen.model.*
1310
import software.amazon.smithy.kotlin.codegen.rendering.protocol.ProtocolGenerator
1411
import software.amazon.smithy.model.shapes.*
1512
import software.amazon.smithy.model.traits.SparseTrait
@@ -87,10 +84,11 @@ open class DeserializeStructGenerator(
8784
ShapeType.LIST,
8885
ShapeType.SET,
8986
-> renderListMemberDeserializer(memberShape, targetShape as CollectionShape)
87+
9088
ShapeType.MAP -> renderMapMemberDeserializer(memberShape, targetShape as MapShape)
89+
9190
ShapeType.STRUCTURE,
9291
ShapeType.UNION,
93-
-> renderShapeDeserializer(memberShape)
9492
ShapeType.BLOB,
9593
ShapeType.BOOLEAN,
9694
ShapeType.STRING,
@@ -104,7 +102,11 @@ open class DeserializeStructGenerator(
104102
ShapeType.DOCUMENT,
105103
ShapeType.BIG_DECIMAL,
106104
ShapeType.BIG_INTEGER,
105+
ShapeType.ENUM,
107106
-> renderShapeDeserializer(memberShape)
107+
108+
ShapeType.INT_ENUM -> error("IntEnum is not supported until Smithy 2.0")
109+
108110
else -> error("Unexpected shape type: ${targetShape.type}")
109111
}
110112
}
@@ -178,14 +180,20 @@ open class DeserializeStructGenerator(
178180
ShapeType.BLOB,
179181
ShapeType.DOCUMENT,
180182
ShapeType.TIMESTAMP,
183+
ShapeType.ENUM,
181184
-> renderEntry(elementShape, nestingLevel, isSparse, parentMemberName)
185+
182186
ShapeType.SET,
183187
ShapeType.LIST,
184188
-> renderListEntry(rootMemberShape, elementShape as CollectionShape, nestingLevel, isSparse, parentMemberName)
189+
185190
ShapeType.MAP -> renderMapEntry(rootMemberShape, elementShape as MapShape, nestingLevel, isSparse, parentMemberName)
186191
ShapeType.UNION,
187192
ShapeType.STRUCTURE,
188193
-> renderNestedStructureEntry(elementShape, nestingLevel, isSparse, parentMemberName)
194+
195+
ShapeType.INT_ENUM -> error("IntEnum is not supported until Smithy 2.0")
196+
189197
else -> error("Unhandled type ${elementShape.type}")
190198
}
191199
}
@@ -383,14 +391,20 @@ open class DeserializeStructGenerator(
383391
ShapeType.BLOB,
384392
ShapeType.DOCUMENT,
385393
ShapeType.TIMESTAMP,
394+
ShapeType.ENUM,
386395
-> renderElement(elementShape, nestingLevel, isSparse, parentMemberName)
396+
387397
ShapeType.LIST,
388398
ShapeType.SET,
389399
-> renderListElement(rootMemberShape, elementShape as CollectionShape, nestingLevel, parentMemberName)
400+
390401
ShapeType.MAP -> renderMapElement(rootMemberShape, elementShape as MapShape, nestingLevel, parentMemberName)
391402
ShapeType.UNION,
392403
ShapeType.STRUCTURE,
393404
-> renderNestedStructureElement(elementShape, nestingLevel, isSparse, parentMemberName)
405+
406+
ShapeType.INT_ENUM -> error("IntEnum is not supported until Smithy 2.0")
407+
394408
else -> error("Unhandled type ${elementShape.type}")
395409
}
396410
}
@@ -510,20 +524,22 @@ open class DeserializeStructGenerator(
510524
// target shape type to deserialize is either the shape itself or member.target
511525
val target = shape.targetOrSelf(ctx.model)
512526

513-
return when (target.type) {
514-
ShapeType.BOOLEAN -> "deserializeBoolean()"
515-
ShapeType.BYTE -> "deserializeByte()"
516-
ShapeType.SHORT -> "deserializeShort()"
517-
ShapeType.INTEGER -> "deserializeInt()"
518-
ShapeType.LONG -> "deserializeLong()"
519-
ShapeType.FLOAT -> "deserializeFloat()"
520-
ShapeType.DOUBLE -> "deserializeDouble()"
521-
ShapeType.DOCUMENT -> "deserializeDocument()"
522-
ShapeType.BLOB -> {
527+
return when {
528+
target.type == ShapeType.BOOLEAN -> "deserializeBoolean()"
529+
target.type == ShapeType.BYTE -> "deserializeByte()"
530+
target.type == ShapeType.SHORT -> "deserializeShort()"
531+
target.type == ShapeType.INTEGER -> "deserializeInt()"
532+
target.type == ShapeType.LONG -> "deserializeLong()"
533+
target.type == ShapeType.FLOAT -> "deserializeFloat()"
534+
target.type == ShapeType.DOUBLE -> "deserializeDouble()"
535+
target.type == ShapeType.DOCUMENT -> "deserializeDocument()"
536+
537+
target.type == ShapeType.BLOB -> {
523538
writer.addImport("decodeBase64Bytes", KotlinDependency.UTILS)
524539
"deserializeString().decodeBase64Bytes()"
525540
}
526-
ShapeType.TIMESTAMP -> {
541+
542+
target.type == ShapeType.TIMESTAMP -> {
527543
writer.addImport(RuntimeTypes.Core.Instant)
528544
val tsFormat = shape
529545
.getTrait(TimestampFormatTrait::class.java)
@@ -537,19 +553,21 @@ open class DeserializeStructGenerator(
537553
else -> throw CodegenException("unknown timestamp format: $tsFormat")
538554
}
539555
}
540-
ShapeType.STRING -> when {
541-
target.hasTrait<@Suppress("DEPRECATION") software.amazon.smithy.model.traits.EnumTrait>() -> {
542-
val enumSymbol = ctx.symbolProvider.toSymbol(target)
543-
writer.addImport(enumSymbol)
544-
"deserializeString().let { ${enumSymbol.name}.fromValue(it) }"
545-
}
546-
else -> "deserializeString()"
556+
557+
target.isEnum -> {
558+
val enumSymbol = ctx.symbolProvider.toSymbol(target)
559+
writer.addImport(enumSymbol)
560+
"deserializeString().let { ${enumSymbol.name}.fromValue(it) }"
547561
}
548-
ShapeType.STRUCTURE, ShapeType.UNION -> {
562+
563+
target.type == ShapeType.STRING -> "deserializeString()"
564+
565+
target.type == ShapeType.STRUCTURE || target.type == ShapeType.UNION -> {
549566
val symbol = ctx.symbolProvider.toSymbol(target)
550567
val deserializerName = symbol.documentDeserializerName()
551568
"$deserializerName(deserializer)"
552569
}
570+
553571
else -> throw CodegenException("unknown deserializer for member: $shape; target: $target")
554572
}
555573
}

smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/serde/SerdeExt.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ fun Shape.serialKind(): String = when (this.type) {
235235
ShapeType.FLOAT -> "SerialKind.Float"
236236
ShapeType.DOUBLE -> "SerialKind.Double"
237237
ShapeType.STRING -> "SerialKind.String"
238+
ShapeType.ENUM -> "SerialKind.Enum"
239+
ShapeType.INT_ENUM -> "SerialKind.IntEnum"
238240
ShapeType.BLOB -> "SerialKind.Blob"
239241
ShapeType.TIMESTAMP -> "SerialKind.Timestamp"
240242
ShapeType.DOCUMENT -> "SerialKind.Document"

0 commit comments

Comments
 (0)