Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/awslabs/smithy-kotlin into …
Browse files Browse the repository at this point in the history
…jmespath-flatten
  • Loading branch information
0marperez committed Dec 13, 2024
2 parents 13d5641 + 4886087 commit fc65e2e
Show file tree
Hide file tree
Showing 53 changed files with 367 additions and 303 deletions.
192 changes: 107 additions & 85 deletions CHANGELOG.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ of your request may disagree and ask that you add one anyway.
"type": "feature",
"description": "Add multiplatform support for URL parsing",
"issues": [
"awslabs/smithy-kotlin#12345"
"smithy-lang/smithy-kotlin#12345"
]
}
```
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# <img alt="Smithy" src="https://github.com/smithy-lang/smithy/blob/main/docs/_static/favicon.png?raw=true" width="28"> Smithy Kotlin
# <img alt="Smithy" src="https://github.com/smithy-lang/smithy/blob/main/docs/_static/smithy-anvil.svg?raw=true" width="32"> Smithy Kotlin

[Smithy](https://smithy.io/2.0/index.html) code generators for [Kotlin](https://kotlinlang.org/).

Expand Down
3 changes: 1 addition & 2 deletions bom/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ fun DependencyConstraintHandler.api(constraintNotation: Any) =

createBomConstraintsAndVersionCatalog()

configurePublishing("smithy-kotlin")

configurePublishing("smithy-kotlin", "smithy-lang")
publishing {
publications {
create("bom", MavenPublication::class) {
Expand Down
2 changes: 1 addition & 1 deletion codegen/smithy-aws-kotlin-codegen/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,4 @@ publishing {
}
}

configurePublishing("smithy-kotlin")
configurePublishing("smithy-kotlin", "smithy-lang")
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class RestJson1 : JsonHttpBindingProtocolGenerator() {

// restjson1 has some different semantics and expectations around empty structures bound via @httpPayload trait
// * empty structures get serialized to `{}`
// see: https://github.com/awslabs/smithy/pull/924
// see: https://github.com/smithy-lang/smithy/pull/924
val requestBindings = resolver.requestBindings(op)
val httpPayload = requestBindings.firstOrNull { it.location == HttpBinding.Location.PAYLOAD }
if (httpPayload != null) {
Expand All @@ -58,7 +58,7 @@ class RestJson1 : JsonHttpBindingProtocolGenerator() {
write("builder.body = #T.fromBytes(#S.encodeToByteArray())", RuntimeTypes.Http.HttpBody, "{}")
}
// Content-Type still needs to be set for non-structured payloads
// https://github.com/awslabs/smithy/blob/main/smithy-aws-protocol-tests/model/restJson1/http-content-type.smithy#L174
// https://github.com/smithy-lang/smithy/blob/main/smithy-aws-protocol-tests/model/restJson1/http-content-type.smithy#L174
write("builder.headers.setMissing(\"Content-Type\", #S)", resolver.determineRequestContentType(op))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,12 @@ class RpcV2Cbor : AwsHttpBindingProtocolGenerator() {
writer: KotlinWriter,
resolver: HttpBindingResolver,
) {
writer.write("builder.headers.setMissing(\"Content-Type\", #S)", resolver.determineRequestContentType(op))
val contentTypeHeader = when {
op.isInputEventStream(ctx.model) -> "application/vnd.amazon.eventstream"
else -> "application/cbor"
}

writer.write("builder.headers.setMissing(\"Content-Type\", #S)", contentTypeHeader)
}

class RpcV2CborHttpBindingResolver(
Expand All @@ -152,17 +157,13 @@ class RpcV2Cbor : AwsHttpBindingProtocolGenerator() {
"application/cbor",
TimestampFormatTrait.Format.UNKNOWN,
) {

override fun httpTrait(operationShape: OperationShape): HttpTrait = HttpTrait
.builder()
.code(200)
.method("POST")
.uri(UriPattern.parse("/service/${serviceShape.id.name}/operation/${operationShape.id.name}"))
.build()

override fun determineRequestContentType(operationShape: OperationShape): String = when {
operationShape.isInputEventStream(model) -> "application/vnd.amazon.eventstream"
else -> "application/cbor"
}
override fun determineRequestContentType(operationShape: OperationShape): String = "application/cbor"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ val RPC_BOUND_PROTOCOLS = setOf(
"awsJson1_1",
"awsQuery",
"ec2Query",
"rpcv2Cbor",
)

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class RestXmlSerdeDescriptorGenerator(
val serialName = getSerialName(member, nameSuffix)
if (serialName.equals("message", ignoreCase = true)) {
// Need to be able to read error messages from "Message" or "message"
// https://github.com/awslabs/smithy-kotlin/issues/352
// https://github.com/smithy-lang/smithy-kotlin/issues/352
traitList.add(RuntimeTypes.Serde.SerdeXml.XmlAliasName, serialName.toggleFirstCharacterCase().dq())
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class RpcV2CborTest {
@service(sdkId: "CborExample")
service CborExample {
version: "1.0.0",
operations: [GetFoo, GetFooStreaming]
operations: [GetFoo, GetFooStreaming, PutFooStreaming]
}
@http(method: "POST", uri: "/foo")
Expand All @@ -34,7 +34,29 @@ class RpcV2CborTest {
}
}
@http(method: "POST", uri: "/put-foo-streaming")
operation PutFooStreaming {
input: PutFooStreamingInput
}
structure PutFooStreamingInput {
room: String
messages: PublishEvents
}
// Model taken from https://smithy.io/2.0/spec/streaming.html#event-streams
@streaming
union PublishEvents {
message: Message
leave: LeaveEvent
}
structure Message {
message: String
}
structure LeaveEvent {}
@streaming
union FooEvents {
up: Movement
Expand Down Expand Up @@ -98,4 +120,29 @@ class RpcV2CborTest {
""".replaceIndent(" ")
getFooMethod.shouldContainOnlyOnceWithDiff(expectedHeaderMutation)
}

@Test
fun testEventStreamContentTypeHeaders() {
val ctx = model.newTestContext("CborExample")

val generator = RpcV2Cbor()
generator.generateProtocolClient(ctx.generationCtx)

ctx.generationCtx.delegator.finalize()
ctx.generationCtx.delegator.flushWriters()

val serializer = ctx.manifest.expectFileString("/src/main/kotlin/com/test/serde/PutFooStreamingOperationSerializer.kt")

// Event stream messages should have `:content-type: application/cbor`
val encodeMessage = serializer.lines("private fun encodePutFooStreamingPublishEventsEventMessage(input: PublishEvents): Message = buildMessage {", "}")
encodeMessage.shouldContainOnlyOnceWithDiff(
"""
addHeader(":content-type", HeaderValue.String("application/cbor"))
""".trimIndent(),
)

// Event stream requests should have Content-Type=application/vnd.amazon.eventstream
val serializeBody = serializer.lines(" override suspend fun serialize(context: ExecutionContext, input: PutFooStreamingRequest): HttpRequestBuilder {", "}")
serializeBody.shouldContainOnlyOnceWithDiff("""builder.headers.setMissing("Content-Type", "application/vnd.amazon.eventstream")""")
}
}
2 changes: 1 addition & 1 deletion codegen/smithy-kotlin-codegen-testutils/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,4 @@ publishing {
}
}

configurePublishing("smithy-kotlin")
configurePublishing("smithy-kotlin", "smithy-lang")
2 changes: 1 addition & 1 deletion codegen/smithy-kotlin-codegen/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,4 @@ publishing {
}
}

configurePublishing("smithy-kotlin")
configurePublishing("smithy-kotlin", "smithy-lang")
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class CodegenVisitor(context: PluginContext) : ShapeVisitor.Default<Unit>() {
// Model pre-processing:
// 1. Start with the model from the plugin context
// 2. Apply integrations
// 3. Flatten error shapes (see: https://github.com/awslabs/smithy/pull/919)
// 3. Flatten error shapes (see: https://github.com/smithy-lang/smithy/pull/919)
// 4. Normalize the operations
for (integration in integrations) {
if (integration.enabledForService(resolvedModel, settings)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ fun interface SectionWriter {
* evaluated [SectionWriter] associated with the same [SectionId]. For writers that wish to
* append to any pre-existing codegen strings in the section, they must explicitly write
* the contents of previousValue to the writer. See the
* [CodeWriter](https://github.com/awslabs/smithy/blob/main/smithy-utils/src/main/java/software/amazon/smithy/utils/CodeWriter.java)
* [CodeWriter](https://github.com/smithy-lang/smithy/blob/main/smithy-utils/src/main/java/software/amazon/smithy/utils/CodeWriter.java)
* documentation for more details
*/
fun write(writer: KotlinWriter, previousValue: String?)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class ShapeValueGenerator(
private fun classDeclaration(writer: KotlinWriter, shape: StructureShape, block: () -> Unit) {
val symbol = symbolProvider.toSymbol(shape)
// invoke the generated DSL builder for the class
writer.writeInline("#L {", symbol.name)
writer.writeInline("#T {", symbol)
.ensureNewline()
.indent()
.call { block() }
Expand Down Expand Up @@ -129,7 +129,7 @@ class ShapeValueGenerator(
val suffix = when {
shape.isEnum -> {
val symbol = symbolProvider.toSymbol(shape)
writer.writeInline("#L.fromValue(", symbol.name)
writer.writeInline("#T.fromValue(", symbol)
")"
}

Expand Down Expand Up @@ -222,7 +222,7 @@ class ShapeValueGenerator(
val currSymbol = generator.symbolProvider.toSymbol(currShape)
val memberName = generator.symbolProvider.toMemberName(member)
val variantName = memberName.replaceFirstChar { c -> c.uppercaseChar() }
writer.writeInline("${currSymbol.name}.$variantName(")
writer.writeInline("#T.#L(", currSymbol, variantName)
generator.instantiateShapeInline(writer, memberShape, valueNode)
writer.writeInline(")")
}
Expand All @@ -243,14 +243,14 @@ class ShapeValueGenerator(
ShapeType.DOUBLE,
ShapeType.FLOAT,
-> {
val symbolName = generator.symbolProvider.toSymbol(currShape).name
val symbol = generator.symbolProvider.toSymbol(currShape)
val symbolMember = when (node.value) {
"Infinity" -> "POSITIVE_INFINITY"
"-Infinity" -> "NEGATIVE_INFINITY"
"NaN" -> "NaN"
else -> throw CodegenException("""Cannot interpret $symbolName value "${node.value}".""")
else -> throw CodegenException("""Cannot interpret $symbol value "${node.value}".""")
}
writer.writeInline("#L", "$symbolName.$symbolMember")
writer.writeInline("#T.#L", symbol, symbolMember)
}

ShapeType.BIG_INTEGER -> writer.writeInline("#T(#S)", RuntimeTypes.Core.Content.BigInteger, node.value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ abstract class HttpBindingProtocolGenerator : ProtocolGenerator {
if (op.isInputEventStream(ctx.model)) {
val eventStreamSerializeFn = eventStreamRequestHandler(ctx, op)
writer.write("builder.body = #T(context, input)", eventStreamSerializeFn)
renderContentTypeHeader(ctx, op, writer, resolver)
} else {
renderSerializeHttpBody(ctx, op, writer)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ open class XmlSerdeDescriptorGenerator(
val objTraits = mutableListOf<SdkFieldDescriptorTrait>()
val serialName = when {
// FIXME - we should be able to remove special casing of errors here which is protocol specific
// see https://github.com/awslabs/smithy-kotlin/issues/350
// see https://github.com/smithy-lang/smithy-kotlin/issues/350
objectShape.hasTrait<ErrorTrait>() -> "Error"
objectShape.hasTrait<XmlNameTrait>() -> objectShape.expectTrait<XmlNameTrait>().value
objectShape.hasTrait<SyntheticClone>() -> objectShape.expectTrait<SyntheticClone>().archetype.name
Expand Down
Loading

0 comments on commit fc65e2e

Please sign in to comment.