in smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpProtocolClientGenerator.kt [131:198]
protected open fun renderOperationSetup(writer: KotlinWriter, opIndex: OperationIndex, op: OperationShape) {
val inputShape = opIndex.getInput(op)
val outputShape = opIndex.getOutput(op)
val httpTrait = httpBindingResolver.httpTrait(op)
val (inputSymbolName, outputSymbolName) = ioSymbolNames(op)
writer.openBlock(
"val op = SdkHttpOperation.build<#L, #L> {", "}",
inputSymbolName,
outputSymbolName
) {
if (inputShape.isPresent) {
writer.write("serializer = ${op.serializerName()}()")
} else {
// no serializer implementation is generated for operations with no input, inline the HTTP
// protocol request from the operation itself
// NOTE: this will never be triggered for AWS models where we preprocess operations to always have inputs/outputs
writer.addImport(RuntimeTypes.Http.Request.HttpRequestBuilder)
writer.addImport(RuntimeTypes.Core.ExecutionContext)
writer.openBlock("serializer = object : HttpSerialize<#Q> {", "}", KotlinTypes.Unit) {
writer.openBlock(
"override suspend fun serialize(context: ExecutionContext, input: #Q): HttpRequestBuilder {",
"}",
KotlinTypes.Unit
) {
writer.write("val builder = HttpRequestBuilder()")
writer.write("builder.method = HttpMethod.#L", httpTrait.method.uppercase())
// NOTE: since there is no input the URI can only be a literal (no labels to fill)
writer.write("builder.url.path = #S", httpTrait.uri.toString())
writer.write("return builder")
}
}
}
writer.declareSection(OperationDeserializerBinding, mapOf(OperationDeserializerBinding.Operation to op)) {
if (outputShape.isPresent) {
write("deserializer = ${op.deserializerName()}()")
} else {
write("deserializer = UnitDeserializer")
}
}
// execution context
writer.openBlock("context {", "}") {
writer.write("expectedHttpStatus = ${httpTrait.code}")
// property from implementing SdkClient
writer.write("service = serviceName")
writer.write("operationName = #S", op.id.name)
// optional endpoint trait
op.getTrait<EndpointTrait>()?.let { endpointTrait ->
val hostPrefix = endpointTrait.hostPrefix.segments.joinToString(separator = "") { segment ->
if (segment.isLabel) {
// hostLabel can only target string shapes
// see: https://awslabs.github.io/smithy/1.0/spec/core/endpoint-traits.html#hostlabel-trait
val member =
inputShape.get().members().first { member -> member.memberName == segment.content }
"\${input.${member.defaultName()}}"
} else {
segment.content
}
}
writer.write("hostPrefix = #S", hostPrefix)
}
}
}
}