Split `CodegenContext` and children (#1473)

This commit splits each of:

* `CodegenContext`,
* `RustSettings`; and
* `CodegenConfig`

into two variants: one for the `rust-codegen` client plugin and another
for the `rust-server-codegen` plugin.

(`CodegenConfig` is a property of `RustSettings`, which is a property of
`CodegenContext`; they constitute pervasive read-only global data that
gets passed around to the code generators).

This allows each plugin to evolve separately, defining different
settings and passing around a tailor-made code-generation context.

Client-specific generators should now use:

* `ClientCodegenContext`,
* `ClientRustSettings`; and
* `ClientCodegenConfig`.

Likewise, server-specific generators should now use:

* `ServerCodegenContext`,
* `ServerRustSettings`; and
* `ServerCodegenConfig`.

This is a more robust and maintainable approach than the current one,
where both generator types have to read possibly null values (because
they don't make sense for a client/server target), and plugins have to
populate settings that are not relevant for the crate they're
generating. For example, the server plugin has to populate and pass
around the settings `renameExceptions`, `includeFluentClient` and
`addMessageToErrors` even though it never uses them and don't make sense
for it.

As of writing these client and server specific classes are very similar,
but in the future they will evolve in separate ways (for example, #1342
will add symbol providers for constrained shapes that only make sense in
a server code-generation context).

Common properties have not been duplicated however. Instead, utilizing
inheritance, code-generation context that is common to _all_ plugins can
be placed in:

* `CoreCodegenContext`,
* `CoreRustSettings`; and
* `CoreCodegenConfig`.

This way, generators that are shared by both client and server can take
in `CoreCodegenContext`. If they need to tweak the code they generate in
small and self-contained places, they can utilize the `CodegenTarget`
flag-like enum to disambiguate, like they have always been doing.

Note this change also makes `RustDecorator`s be targeted for clients or
servers, by making them generic over the code-generation context. When
loading the decorators from the classpath and combining them into one in
the executed smithy-rs plugin, all of them need to either target clients
or target servers. This makes sense: after all, all of the decorators
that conform the AWS Rust SDK are client-specific.

Closes #828.
This commit is contained in:
david-perez 2022-06-21 21:12:31 +02:00 committed by GitHub
parent 1446681c0a
commit 5d6d8843cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
116 changed files with 1304 additions and 974 deletions

View File

@ -5,6 +5,7 @@
package software.amazon.smithy.rustsdk
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.customizations.DocsRsMetadataDecorator
import software.amazon.smithy.rust.codegen.smithy.customizations.DocsRsMetadataSettings
import software.amazon.smithy.rust.codegen.smithy.customizations.RetryConfigDecorator
@ -51,7 +52,7 @@ val DECORATORS = listOf(
DocsRsMetadataDecorator(DocsRsMetadataSettings(targets = listOf("x86_64-unknown-linux-gnu"), allFeatures = true))
)
class AwsCodegenDecorator : CombinedCodegenDecorator(DECORATORS) {
class AwsCodegenDecorator : CombinedCodegenDecorator<ClientCodegenContext>(DECORATORS) {
override val name: String = "AwsSdkCodegenDecorator"
override val order: Byte = -1
}

View File

@ -22,7 +22,8 @@ import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.withBlock
import software.amazon.smithy.rust.codegen.rustlang.withBlockTemplate
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.customize.OperationCustomization
@ -36,7 +37,7 @@ import software.amazon.smithy.rust.codegen.util.dq
import software.amazon.smithy.rust.codegen.util.expectTrait
import software.amazon.smithy.rust.codegen.util.orNull
class AwsEndpointDecorator : RustCodegenDecorator {
class AwsEndpointDecorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "AwsEndpoint"
override val order: Byte = 0
@ -46,14 +47,14 @@ class AwsEndpointDecorator : RustCodegenDecorator {
}
override fun configCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<ConfigCustomization>
): List<ConfigCustomization> {
return baseCustomizations + EndpointConfigCustomization(codegenContext, endpoints)
}
override fun operationCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
operation: OperationShape,
baseCustomizations: List<OperationCustomization>
): List<OperationCustomization> {
@ -61,18 +62,18 @@ class AwsEndpointDecorator : RustCodegenDecorator {
}
override fun libRsCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<LibRsCustomization>
): List<LibRsCustomization> {
return baseCustomizations + PubUseEndpoint(codegenContext.runtimeConfig)
}
}
class EndpointConfigCustomization(private val codegenContext: CodegenContext, private val endpointData: ObjectNode) :
class EndpointConfigCustomization(private val coreCodegenContext: CoreCodegenContext, private val endpointData: ObjectNode) :
ConfigCustomization() {
private val runtimeConfig = codegenContext.runtimeConfig
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val resolveAwsEndpoint = runtimeConfig.awsEndpoint().asType().copy(name = "ResolveAwsEndpoint")
private val moduleUseName = codegenContext.moduleUseName()
private val moduleUseName = coreCodegenContext.moduleUseName()
override fun section(section: ServiceConfig): Writable = writable {
when (section) {
is ServiceConfig.ConfigStruct -> rust(
@ -116,7 +117,7 @@ class EndpointConfigCustomization(private val codegenContext: CodegenContext, pr
"aws_types" to awsTypes(runtimeConfig).asType()
)
ServiceConfig.BuilderBuild -> {
val resolverGenerator = EndpointResolverGenerator(codegenContext, endpointData)
val resolverGenerator = EndpointResolverGenerator(coreCodegenContext, endpointData)
rust(
"""
endpoint_resolver: self.endpoint_resolver.unwrap_or_else(||
@ -163,9 +164,9 @@ class PubUseEndpoint(private val runtimeConfig: RuntimeConfig) : LibRsCustomizat
}
}
class EndpointResolverGenerator(codegenContext: CodegenContext, private val endpointData: ObjectNode) {
private val runtimeConfig = codegenContext.runtimeConfig
private val endpointPrefix = codegenContext.serviceShape.expectTrait<ServiceTrait>().endpointPrefix
class EndpointResolverGenerator(coreCodegenContext: CoreCodegenContext, private val endpointData: ObjectNode) {
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val endpointPrefix = coreCodegenContext.serviceShape.expectTrait<ServiceTrait>().endpointPrefix
private val awsEndpoint = runtimeConfig.awsEndpoint().asType()
private val awsTypes = runtimeConfig.awsTypes().asType()
private val codegenScope =

View File

@ -19,7 +19,8 @@ import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.RustCrate
@ -72,13 +73,13 @@ private class AwsClientGenerics(private val types: Types) : FluentClientGenerics
override fun sendBounds(input: Symbol, output: Symbol, error: RuntimeType): Writable = writable { }
}
class AwsFluentClientDecorator : RustCodegenDecorator {
class AwsFluentClientDecorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "FluentClient"
// Must run after the AwsPresigningDecorator so that the presignable trait is correctly added to operations
override val order: Byte = (AwsPresigningDecorator.ORDER + 1).toByte()
override fun extras(codegenContext: CodegenContext, rustCrate: RustCrate) {
override fun extras(codegenContext: ClientCodegenContext, rustCrate: RustCrate) {
val types = Types(codegenContext.runtimeConfig)
FluentClientGenerator(
codegenContext,
@ -97,7 +98,7 @@ class AwsFluentClientDecorator : RustCodegenDecorator {
}
override fun libRsCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<LibRsCustomization>
): List<LibRsCustomization> {
return baseCustomizations + object : LibRsCustomization() {
@ -181,12 +182,12 @@ private class AwsFluentClientExtensions(types: Types) {
}
}
private class AwsFluentClientDocs(codegenContext: CodegenContext) : FluentClientCustomization() {
private val serviceName = codegenContext.serviceShape.expectTrait<TitleTrait>().value
private val serviceShape = codegenContext.serviceShape
private val crateName = codegenContext.moduleUseName()
private class AwsFluentClientDocs(coreCodegenContext: CoreCodegenContext) : FluentClientCustomization() {
private val serviceName = coreCodegenContext.serviceShape.expectTrait<TitleTrait>().value
private val serviceShape = coreCodegenContext.serviceShape
private val crateName = coreCodegenContext.moduleUseName()
private val codegenScope =
arrayOf("aws_config" to codegenContext.runtimeConfig.awsConfig().copy(scope = DependencyScope.Dev).asType())
arrayOf("aws_config" to coreCodegenContext.runtimeConfig.awsConfig().copy(scope = DependencyScope.Dev).asType())
// Usage docs on STS must be suppressed—aws-config cannot be added as a dev-dependency because it would create
// a circular dependency

View File

@ -27,7 +27,8 @@ import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.withBlock
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.smithy.customize.OperationCustomization
import software.amazon.smithy.rust.codegen.smithy.customize.OperationSection
@ -84,7 +85,7 @@ internal val PRESIGNABLE_OPERATIONS by lazy {
class AwsPresigningDecorator internal constructor(
private val presignableOperations: Map<ShapeId, PresignableOperation> = PRESIGNABLE_OPERATIONS
) : RustCodegenDecorator {
) : RustCodegenDecorator<ClientCodegenContext> {
companion object {
const val ORDER: Byte = 0
}
@ -93,7 +94,7 @@ class AwsPresigningDecorator internal constructor(
override val order: Byte = ORDER
override fun operationCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
operation: OperationShape,
baseCustomizations: List<OperationCustomization>
): List<OperationCustomization> = baseCustomizations + listOf(AwsInputPresignedMethod(codegenContext, operation))
@ -129,11 +130,11 @@ class AwsPresigningDecorator internal constructor(
}
class AwsInputPresignedMethod(
private val codegenContext: CodegenContext,
private val coreCodegenContext: CoreCodegenContext,
private val operationShape: OperationShape
) : OperationCustomization() {
private val runtimeConfig = codegenContext.runtimeConfig
private val symbolProvider = codegenContext.symbolProvider
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val symbolProvider = coreCodegenContext.symbolProvider
private val codegenScope = arrayOf(
"Error" to AwsRuntimeType.Presigning.member("config::Error"),
@ -158,7 +159,7 @@ class AwsInputPresignedMethod(
val presignableOp = PRESIGNABLE_OPERATIONS.getValue(operationShape.id)
val makeOperationOp = if (presignableOp.hasModelTransforms()) {
codegenContext.model.expectShape(syntheticShapeId(operationShape.id), OperationShape::class.java)
coreCodegenContext.model.expectShape(syntheticShapeId(operationShape.id), OperationShape::class.java)
} else {
section.operationShape
}
@ -166,9 +167,9 @@ class AwsInputPresignedMethod(
val protocol = section.protocol
MakeOperationGenerator(
codegenContext,
coreCodegenContext,
protocol,
HttpBoundProtocolPayloadGenerator(codegenContext, protocol),
HttpBoundProtocolPayloadGenerator(coreCodegenContext, protocol),
// Prefixed with underscore to avoid colliding with modeled functions
functionName = makeOperationFn,
public = false,

View File

@ -10,12 +10,11 @@ import org.jsoup.nodes.Element
import org.jsoup.nodes.TextNode
import software.amazon.smithy.model.traits.DocumentationTrait
import software.amazon.smithy.rust.codegen.rustlang.raw
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RustCrate
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.generators.ManifestCustomizations
import software.amazon.smithy.rust.codegen.util.getTrait
import java.lang.StringBuilder
import java.util.logging.Logger
// Use a sigil that should always be unique in the text to fix line breaks and spaces
@ -26,16 +25,16 @@ private const val SPACE_SIGIL = "[[smithy-rs-nbsp]]"
/**
* Generates a README.md for each service crate for display on crates.io.
*/
class AwsReadmeDecorator : RustCodegenDecorator {
class AwsReadmeDecorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "AwsReadmeDecorator"
override val order: Byte = 0
private val logger: Logger = Logger.getLogger(javaClass.name)
override fun crateManifestCustomizations(codegenContext: CodegenContext): ManifestCustomizations =
override fun crateManifestCustomizations(codegenContext: ClientCodegenContext): ManifestCustomizations =
mapOf("package" to mapOf("readme" to "README.md"))
override fun extras(codegenContext: CodegenContext, rustCrate: RustCrate) {
override fun extras(codegenContext: ClientCodegenContext, rustCrate: RustCrate) {
rustCrate.withFile("README.md") { writer ->
val description = normalizeDescription(
codegenContext.moduleName,

View File

@ -6,16 +6,16 @@
package software.amazon.smithy.rustsdk
import software.amazon.smithy.rust.codegen.rustlang.raw
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RustCrate
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
class CrateLicenseDecorator : RustCodegenDecorator {
class CrateLicenseDecorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "CrateLicense"
override val order: Byte = 0
override fun extras(codegenContext: CodegenContext, rustCrate: RustCrate) {
override fun extras(codegenContext: ClientCodegenContext, rustCrate: RustCrate) {
rustCrate.withFile("LICENSE") {
val license = this::class.java.getResource("/LICENSE").readText()
it.raw(license)

View File

@ -11,7 +11,7 @@ import software.amazon.smithy.rust.codegen.rustlang.asType
import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.customize.OperationCustomization
@ -22,19 +22,19 @@ import software.amazon.smithy.rust.codegen.smithy.generators.LibRsSection
import software.amazon.smithy.rust.codegen.smithy.generators.config.ConfigCustomization
import software.amazon.smithy.rust.codegen.smithy.generators.config.ServiceConfig
class CredentialsProviderDecorator : RustCodegenDecorator {
class CredentialsProviderDecorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "CredentialsProvider"
override val order: Byte = 0
override fun configCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<ConfigCustomization>
): List<ConfigCustomization> {
return baseCustomizations + CredentialProviderConfig(codegenContext.runtimeConfig)
}
override fun operationCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
operation: OperationShape,
baseCustomizations: List<OperationCustomization>
): List<OperationCustomization> {
@ -42,7 +42,7 @@ class CredentialsProviderDecorator : RustCodegenDecorator {
}
override fun libRsCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<LibRsCustomization>
): List<LibRsCustomization> {
return baseCustomizations + PubUseCredentials(codegenContext.runtimeConfig)

View File

@ -10,7 +10,7 @@ import software.amazon.smithy.rust.codegen.rustlang.CratesIo
import software.amazon.smithy.rust.codegen.rustlang.DependencyScope
import software.amazon.smithy.rust.codegen.rustlang.Writable
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.generators.LibRsCustomization
@ -18,12 +18,12 @@ import software.amazon.smithy.rust.codegen.smithy.generators.LibRsSection
import java.nio.file.Files
import java.nio.file.Paths
class IntegrationTestDecorator : RustCodegenDecorator {
class IntegrationTestDecorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "IntegrationTest"
override val order: Byte = 0
override fun libRsCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<LibRsCustomization>
): List<LibRsCustomization> {
val integrationTestPath = Paths.get(SdkSettings.from(codegenContext.settings).integrationTestPath)

View File

@ -10,7 +10,8 @@ import software.amazon.smithy.rust.codegen.rustlang.Writable
import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.customize.OperationCustomization
@ -69,19 +70,19 @@ fn test_1() {
}
*/
class RegionDecorator : RustCodegenDecorator {
class RegionDecorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "Region"
override val order: Byte = 0
override fun configCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<ConfigCustomization>
): List<ConfigCustomization> {
return baseCustomizations + RegionProviderConfig(codegenContext)
}
override fun operationCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
operation: OperationShape,
baseCustomizations: List<OperationCustomization>
): List<OperationCustomization> {
@ -89,16 +90,16 @@ class RegionDecorator : RustCodegenDecorator {
}
override fun libRsCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<LibRsCustomization>
): List<LibRsCustomization> {
return baseCustomizations + PubUseRegion(codegenContext.runtimeConfig)
}
}
class RegionProviderConfig(codegenContext: CodegenContext) : ConfigCustomization() {
private val region = region(codegenContext.runtimeConfig)
private val moduleUseName = codegenContext.moduleUseName()
class RegionProviderConfig(coreCodegenContext: CoreCodegenContext) : ConfigCustomization() {
private val region = region(coreCodegenContext.runtimeConfig)
private val moduleUseName = coreCodegenContext.moduleUseName()
private val codegenScope = arrayOf("Region" to region.member("Region"))
override fun section(section: ServiceConfig) = writable {
when (section) {

View File

@ -9,19 +9,19 @@ import software.amazon.smithy.model.shapes.OperationShape
import software.amazon.smithy.rust.codegen.rustlang.asType
import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.customize.OperationCustomization
import software.amazon.smithy.rust.codegen.smithy.customize.OperationSection
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
class RetryPolicyDecorator : RustCodegenDecorator {
class RetryPolicyDecorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "RetryPolicy"
override val order: Byte = 0
override fun operationCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
operation: OperationShape,
baseCustomizations: List<OperationCustomization>
): List<OperationCustomization> {

View File

@ -10,7 +10,7 @@ import software.amazon.smithy.rust.codegen.rustlang.Writable
import software.amazon.smithy.rust.codegen.rustlang.asType
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.smithy.RustCrate
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
@ -23,18 +23,18 @@ import software.amazon.smithy.rust.codegen.smithy.generators.config.ServiceConfi
* - `From<&aws_types::SdkConfig> for <service>::config::Builder`: Enabling customization
* - `pub fn new(&aws_types::SdkConfig) -> <service>::Config`: Direct construction without customization
*/
class SdkConfigDecorator : RustCodegenDecorator {
class SdkConfigDecorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "SdkConfig"
override val order: Byte = 0
override fun configCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<ConfigCustomization>
): List<ConfigCustomization> {
return baseCustomizations + NewFromShared(codegenContext.runtimeConfig)
}
override fun extras(codegenContext: CodegenContext, rustCrate: RustCrate) {
override fun extras(codegenContext: ClientCodegenContext, rustCrate: RustCrate) {
val codegenScope = arrayOf(
"SdkConfig" to awsTypes(runtimeConfig = codegenContext.runtimeConfig).asType().member("sdk_config::SdkConfig")
)

View File

@ -5,7 +5,7 @@
package software.amazon.smithy.rustsdk
import software.amazon.smithy.model.node.ObjectNode
import software.amazon.smithy.rust.codegen.smithy.RustSettings
import software.amazon.smithy.rust.codegen.smithy.CoreRustSettings
import software.amazon.smithy.rust.codegen.util.orNull
/**
@ -13,8 +13,8 @@ import software.amazon.smithy.rust.codegen.util.orNull
*/
class SdkSettings private constructor(private val awsSdk: ObjectNode?) {
companion object {
fun from(rustSettings: RustSettings): SdkSettings =
SdkSettings(rustSettings.customizationConfig?.getObjectMember("awsSdk")?.orNull())
fun from(coreRustSettings: CoreRustSettings): SdkSettings =
SdkSettings(coreRustSettings.customizationConfig?.getObjectMember("awsSdk")?.orNull())
}
/** Path to AWS SDK integration tests */

View File

@ -8,17 +8,17 @@ package software.amazon.smithy.rustsdk
import software.amazon.smithy.rust.codegen.rustlang.Writable
import software.amazon.smithy.rust.codegen.rustlang.docs
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.generators.config.ConfigCustomization
import software.amazon.smithy.rust.codegen.smithy.generators.config.ServiceConfig
class ServiceConfigDecorator : RustCodegenDecorator {
class ServiceConfigDecorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "ServiceConfigGenerator"
override val order: Byte = 0
override fun configCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<ConfigCustomization>
): List<ConfigCustomization> = baseCustomizations + SharedConfigDocsCustomization()
}

View File

@ -19,7 +19,8 @@ import software.amazon.smithy.rust.codegen.rustlang.asType
import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.customize.OperationCustomization
@ -42,14 +43,14 @@ import software.amazon.smithy.rust.codegen.util.isInputEventStream
* - sets a default `OperationSigningConfig` A future enhancement will customize this for specific services that need
* different behavior.
*/
class SigV4SigningDecorator : RustCodegenDecorator {
class SigV4SigningDecorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "SigV4Signing"
override val order: Byte = 0
private fun applies(codegenContext: CodegenContext): Boolean = codegenContext.serviceShape.hasTrait<SigV4Trait>()
private fun applies(coreCodegenContext: CoreCodegenContext): Boolean = coreCodegenContext.serviceShape.hasTrait<SigV4Trait>()
override fun configCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<ConfigCustomization>
): List<ConfigCustomization> {
return baseCustomizations.letIf(applies(codegenContext)) { customizations ->
@ -62,7 +63,7 @@ class SigV4SigningDecorator : RustCodegenDecorator {
}
override fun operationCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
operation: OperationShape,
baseCustomizations: List<OperationCustomization>
): List<OperationCustomization> {

View File

@ -12,7 +12,7 @@ import software.amazon.smithy.rust.codegen.rustlang.asType
import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.customize.OperationCustomization
@ -28,19 +28,19 @@ import software.amazon.smithy.rust.codegen.util.expectTrait
/**
* Inserts a UserAgent configuration into the operation
*/
class UserAgentDecorator : RustCodegenDecorator {
class UserAgentDecorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "UserAgent"
override val order: Byte = 10
override fun configCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<ConfigCustomization>
): List<ConfigCustomization> {
return baseCustomizations + AppNameCustomization(codegenContext.runtimeConfig)
}
override fun libRsCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<LibRsCustomization>
): List<LibRsCustomization> {
// We are generating an AWS SDK, the service needs to have the AWS service trait
@ -49,7 +49,7 @@ class UserAgentDecorator : RustCodegenDecorator {
}
override fun operationCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
operation: OperationShape,
baseCustomizations: List<OperationCustomization>
): List<OperationCustomization> {

View File

@ -10,20 +10,23 @@ import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.rust.codegen.rustlang.Writable
import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.customize.OperationCustomization
import software.amazon.smithy.rust.codegen.smithy.customize.OperationSection
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.letIf
class ApiGatewayDecorator : RustCodegenDecorator {
class ApiGatewayDecorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "ApiGateway"
override val order: Byte = 0
private fun applies(codegenContext: CodegenContext) = codegenContext.serviceShape.id == ShapeId.from("com.amazonaws.apigateway#BackplaneControlService")
private fun applies(coreCodegenContext: CoreCodegenContext) =
coreCodegenContext.serviceShape.id == ShapeId.from("com.amazonaws.apigateway#BackplaneControlService")
override fun operationCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
operation: OperationShape,
baseCustomizations: List<OperationCustomization>
): List<OperationCustomization> {

View File

@ -11,11 +11,12 @@ import software.amazon.smithy.model.shapes.ServiceShape
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.model.traits.AuthTrait
import software.amazon.smithy.model.transform.ModelTransformer
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
private fun String.shapeId() = ShapeId.from(this)
// / STS (and possibly other services) need to have auth manually set to []
class DisabledAuthDecorator : RustCodegenDecorator {
class DisabledAuthDecorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "OptionalAuth"
override val order: Byte = 0

View File

@ -8,10 +8,11 @@ package software.amazon.smithy.rustsdk.customize.ec2
import software.amazon.smithy.model.Model
import software.amazon.smithy.model.shapes.ServiceShape
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.letIf
class Ec2Decorator : RustCodegenDecorator {
class Ec2Decorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "Ec2"
override val order: Byte = 0
private val ec2 = ShapeId.from("com.amazonaws.ec2#AmazonEC2")

View File

@ -7,19 +7,21 @@ package software.amazon.smithy.rustsdk.customize.glacier
import software.amazon.smithy.model.shapes.OperationShape
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.customize.OperationCustomization
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
val Glacier: ShapeId = ShapeId.from("com.amazonaws.glacier#Glacier")
class GlacierDecorator : RustCodegenDecorator {
class GlacierDecorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "Glacier"
override val order: Byte = 0
private fun applies(codegenContext: CodegenContext) = codegenContext.serviceShape.id == Glacier
private fun applies(coreCodegenContext: CoreCodegenContext) = coreCodegenContext.serviceShape.id == Glacier
override fun operationCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
operation: OperationShape,
baseCustomizations: List<OperationCustomization>
): List<OperationCustomization> {

View File

@ -15,7 +15,7 @@ import software.amazon.smithy.model.transform.ModelTransformer
import software.amazon.smithy.rust.codegen.rustlang.Writable
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.customize.OperationCustomization
import software.amazon.smithy.rust.codegen.smithy.customize.OperationSection
@ -28,12 +28,13 @@ import java.util.logging.Logger
val Route53: ShapeId = ShapeId.from("com.amazonaws.route53#AWSDnsV20130401")
class Route53Decorator : RustCodegenDecorator {
class Route53Decorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "Route53"
override val order: Byte = 0
private val logger: Logger = Logger.getLogger(javaClass.name)
private fun applies(service: ServiceShape) = service.id == Route53
override fun transformModel(service: ServiceShape, model: Model): Model {
return model.letIf(applies(service)) {
ModelTransformer.create().mapShapes(model) { shape ->
@ -46,7 +47,7 @@ class Route53Decorator : RustCodegenDecorator {
}
override fun operationCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
operation: OperationShape,
baseCustomizations: List<OperationCustomization>
): List<OperationCustomization> {

View File

@ -16,7 +16,8 @@ import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.generators.LibRsCustomization
@ -29,36 +30,36 @@ import software.amazon.smithy.rustsdk.AwsRuntimeType
/**
* Top level decorator for S3
* */
class S3Decorator : RustCodegenDecorator {
*/
class S3Decorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "S3ExtendedError"
override val order: Byte = 0
private fun applies(serviceId: ShapeId) =
serviceId == ShapeId.from("com.amazonaws.s3#AmazonS3")
override fun protocols(serviceId: ShapeId, currentProtocols: ProtocolMap): ProtocolMap {
return currentProtocols.letIf(applies(serviceId)) {
override fun protocols(
serviceId: ShapeId,
currentProtocols: ProtocolMap<ClientCodegenContext>
): ProtocolMap<ClientCodegenContext> =
currentProtocols.letIf(applies(serviceId)) {
it + mapOf(
RestXmlTrait.ID to RestXmlFactory { protocolConfig ->
S3(protocolConfig)
}
)
}
}
override fun libRsCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<LibRsCustomization>
): List<LibRsCustomization> {
return baseCustomizations.letIf(applies(codegenContext.serviceShape.id)) {
it + S3PubUse()
}
): List<LibRsCustomization> = baseCustomizations.letIf(applies(codegenContext.serviceShape.id)) {
it + S3PubUse()
}
}
class S3(codegenContext: CodegenContext) : RestXml(codegenContext) {
private val runtimeConfig = codegenContext.runtimeConfig
class S3(coreCodegenContext: CoreCodegenContext) : RestXml(coreCodegenContext) {
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val errorScope = arrayOf(
"Bytes" to RuntimeType.Bytes,
"Error" to RuntimeType.GenericError(runtimeConfig),

View File

@ -10,7 +10,7 @@ import software.amazon.smithy.model.node.ObjectNode
import software.amazon.smithy.rust.codegen.rustlang.CargoDependency
import software.amazon.smithy.rust.codegen.rustlang.asType
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.CodegenVisitor
import software.amazon.smithy.rust.codegen.smithy.RustCrate
import software.amazon.smithy.rust.codegen.smithy.customizations.AllowLintsGenerator
@ -124,27 +124,25 @@ internal class EndpointConfigCustomizationTest {
private fun validateEndpointCustomizationForService(service: String, test: ((RustCrate) -> Unit)? = null) {
val (context, testDir) = generatePluginContext(model, service = service, runtimeConfig = AwsTestRuntimeConfig)
val codegenDecorator = object : RustCodegenDecorator {
val codegenDecorator = object : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "tests and config"
override val order: Byte = 0
override fun configCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<ConfigCustomization>
): List<ConfigCustomization> {
return baseCustomizations + stubConfigCustomization("a") + EndpointConfigCustomization(
): List<ConfigCustomization> =
baseCustomizations + stubConfigCustomization("a") + EndpointConfigCustomization(
codegenContext,
endpointConfig
) + stubConfigCustomization("b")
}
override fun libRsCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<LibRsCustomization>
): List<LibRsCustomization> {
return baseCustomizations + PubUseEndpoint(AwsTestRuntimeConfig) + AllowLintsGenerator(listOf("dead_code"), listOf(), listOf())
}
): List<LibRsCustomization> =
baseCustomizations + PubUseEndpoint(AwsTestRuntimeConfig) + AllowLintsGenerator(listOf("dead_code"), listOf(), listOf())
override fun extras(codegenContext: CodegenContext, rustCrate: RustCrate) {
override fun extras(codegenContext: ClientCodegenContext, rustCrate: RustCrate) {
if (test != null) {
test(rustCrate)
}

View File

@ -6,6 +6,7 @@
package software.amazon.smithy.rustsdk
import org.junit.jupiter.api.Test
import software.amazon.smithy.rust.codegen.smithy.CoreRustSettings
import software.amazon.smithy.rust.codegen.testutil.TestWorkspace
import software.amazon.smithy.rust.codegen.testutil.rustSettings
import software.amazon.smithy.rust.codegen.testutil.validateConfigCustomizations
@ -14,7 +15,21 @@ internal class RegionProviderConfigTest {
@Test
fun `generates a valid config`() {
val project = TestWorkspace.testProject()
val codegenContext = awsTestCodegenContext().copy(settings = project.rustSettings())
val projectSettings = project.rustSettings()
val coreRustSettings = CoreRustSettings(
service = projectSettings.service,
moduleName = projectSettings.moduleName,
moduleVersion = projectSettings.moduleVersion,
moduleAuthors = projectSettings.moduleAuthors,
moduleDescription = projectSettings.moduleDescription,
moduleRepository = projectSettings.moduleRepository,
runtimeConfig = AwsTestRuntimeConfig,
codegenConfig = projectSettings.codegenConfig,
license = projectSettings.license,
examplesUri = projectSettings.examplesUri,
customizationConfig = projectSettings.customizationConfig,
)
val codegenContext = awsTestCodegenContext(coreRustSettings = coreRustSettings)
validateConfigCustomizations(RegionProviderConfig(codegenContext), project)
}
}

View File

@ -6,10 +6,12 @@
package software.amazon.smithy.rustsdk
import software.amazon.smithy.model.Model
import software.amazon.smithy.rust.codegen.smithy.CoreRustSettings
import software.amazon.smithy.rust.codegen.smithy.RuntimeCrateLocation
import software.amazon.smithy.rust.codegen.testutil.TestRuntimeConfig
import software.amazon.smithy.rust.codegen.testutil.asSmithyModel
import software.amazon.smithy.rust.codegen.testutil.testCodegenContext
import software.amazon.smithy.rust.codegen.testutil.testRustSettings
import java.io.File
// In aws-sdk-codegen, the working dir when gradle runs tests is actually `./aws`. So, to find the smithy runtime, we need
@ -22,5 +24,8 @@ val AwsTestRuntimeConfig = TestRuntimeConfig.copy(
}
)
fun awsTestCodegenContext(model: Model? = null) =
testCodegenContext(model ?: "namespace test".asSmithyModel()).copy(runtimeConfig = AwsTestRuntimeConfig)
fun awsTestCodegenContext(model: Model? = null, coreRustSettings: CoreRustSettings?) =
testCodegenContext(
model ?: "namespace test".asSmithyModel(),
settings = coreRustSettings ?: testRustSettings(runtimeConfig = AwsTestRuntimeConfig)
)

View File

@ -11,9 +11,10 @@ import software.amazon.smithy.codegen.core.ReservedWordSymbolProvider
import software.amazon.smithy.model.Model
import software.amazon.smithy.model.shapes.ServiceShape
import software.amazon.smithy.rust.codegen.rustlang.RustReservedWordSymbolProvider
import software.amazon.smithy.rust.codegen.server.smithy.customizations.ServerRequiredCustomizations
import software.amazon.smithy.rust.codegen.smithy.BaseSymbolMetadataProvider
import software.amazon.smithy.rust.codegen.smithy.DefaultConfig
import software.amazon.smithy.rust.codegen.smithy.EventStreamSymbolProvider
import software.amazon.smithy.rust.codegen.smithy.ServerCodegenContext
import software.amazon.smithy.rust.codegen.smithy.StreamingShapeMetadataProvider
import software.amazon.smithy.rust.codegen.smithy.StreamingShapeSymbolProvider
import software.amazon.smithy.rust.codegen.smithy.SymbolVisitor
@ -41,7 +42,8 @@ class PythonCodegenServerPlugin : SmithyBuildPlugin {
// - location (e.g. the mutate section of an operation)
// - context (e.g. the of the operation)
// - writer: The active RustWriter at the given location
val codegenDecorator = CombinedCodegenDecorator.fromClasspath(context)
val codegenDecorator: CombinedCodegenDecorator<ServerCodegenContext> =
CombinedCodegenDecorator.fromClasspath(context, ServerRequiredCustomizations())
// PythonServerCodegenVisitor is the main driver of code generation that traverses the model and generates code
logger.info("Loaded plugin to generate Rust/Python bindings for the server SSDK for projection ${context.projectionName}")
@ -58,7 +60,7 @@ class PythonCodegenServerPlugin : SmithyBuildPlugin {
fun baseSymbolProvider(
model: Model,
serviceShape: ServiceShape,
symbolVisitorConfig: SymbolVisitorConfig = DefaultConfig
symbolVisitorConfig: SymbolVisitorConfig,
) =
SymbolVisitor(model, serviceShape = serviceShape, config = symbolVisitorConfig)
// Rename a set of symbols that do not implement `PyClass` and have been wrapped in

View File

@ -16,9 +16,9 @@ import software.amazon.smithy.rust.codegen.server.python.smithy.generators.Pytho
import software.amazon.smithy.rust.codegen.server.python.smithy.generators.PythonServerStructureGenerator
import software.amazon.smithy.rust.codegen.server.smithy.ServerCodegenVisitor
import software.amazon.smithy.rust.codegen.server.smithy.protocols.ServerProtocolLoader
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.DefaultPublicModules
import software.amazon.smithy.rust.codegen.smithy.RustCrate
import software.amazon.smithy.rust.codegen.smithy.ServerCodegenContext
import software.amazon.smithy.rust.codegen.smithy.SymbolVisitorConfig
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.generators.BuilderGenerator
@ -30,18 +30,21 @@ import software.amazon.smithy.rust.codegen.util.getTrait
* Entrypoint for Python server-side code generation. This class will walk the in-memory model and
* generate all the needed types by calling the accept() function on the available shapes.
*
* This class inherits from [ServerCodegenVisitor] since it uses most of the functionlities of the super class
* This class inherits from [ServerCodegenVisitor] since it uses most of the functionalities of the super class
* and have to override the symbol provider with [PythonServerSymbolProvider].
*/
class PythonServerCodegenVisitor(context: PluginContext, codegenDecorator: RustCodegenDecorator) :
ServerCodegenVisitor(context, codegenDecorator) {
class PythonServerCodegenVisitor(
context: PluginContext,
codegenDecorator: RustCodegenDecorator<ServerCodegenContext>
) : ServerCodegenVisitor(context, codegenDecorator) {
init {
val symbolVisitorConfig =
SymbolVisitorConfig(
runtimeConfig = settings.runtimeConfig,
codegenConfig = settings.codegenConfig,
handleRequired = true
renameExceptions = false,
handleRequired = true,
handleRustBoxing = true,
)
val baseModel = baselineTransform(context.model)
val service = settings.getService(baseModel)
@ -61,7 +64,7 @@ class PythonServerCodegenVisitor(context: PluginContext, codegenDecorator: RustC
codegenDecorator.symbolProvider(generator.symbolProvider(model, baseProvider))
// Override `codegenContext` which carries the symbolProvider.
codegenContext = CodegenContext(model, symbolProvider, service, protocol, settings, target = CodegenTarget.SERVER)
codegenContext = ServerCodegenContext(model, symbolProvider, service, protocol, settings)
// Override `rustCrate` which carries the symbolProvider.
rustCrate = RustCrate(context.fileManifest, symbolProvider, DefaultPublicModules, settings.codegenConfig)

View File

@ -12,8 +12,8 @@ import software.amazon.smithy.rust.codegen.rustlang.rustBlock
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.server.python.smithy.PythonServerRuntimeType
import software.amazon.smithy.rust.codegen.server.smithy.customizations.AddInternalServerErrorToAllOperationsDecorator
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.smithy.ServerCodegenContext
import software.amazon.smithy.rust.codegen.smithy.customize.CombinedCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.generators.LibRsCustomization
@ -27,12 +27,12 @@ import software.amazon.smithy.rust.codegen.smithy.generators.ManifestCustomizati
* name = "$CRATE_NAME"
* crate-type = ["cdylib"]
*/
class CdylibManifestDecorator : RustCodegenDecorator {
class CdylibManifestDecorator : RustCodegenDecorator<ServerCodegenContext> {
override val name: String = "CdylibDecorator"
override val order: Byte = 0
override fun crateManifestCustomizations(
codegenContext: CodegenContext
codegenContext: ServerCodegenContext
): ManifestCustomizations =
mapOf("lib" to mapOf("name" to codegenContext.settings.moduleName, "crate-type" to listOf("cdylib")))
}
@ -57,16 +57,15 @@ class PubUsePythonTypes(private val runtimeConfig: RuntimeConfig) : LibRsCustomi
/**
* Decorator applying the customization from [PubUsePythonTypes] class.
*/
class PubUsePythonTypesDecorator : RustCodegenDecorator {
class PubUsePythonTypesDecorator : RustCodegenDecorator<ServerCodegenContext> {
override val name: String = "PubUsePythonTypesDecorator"
override val order: Byte = 0
override fun libRsCustomizations(
codegenContext: CodegenContext,
codegenContext: ServerCodegenContext,
baseCustomizations: List<LibRsCustomization>
): List<LibRsCustomization> {
return baseCustomizations + PubUsePythonTypes(codegenContext.runtimeConfig)
}
): List<LibRsCustomization> =
baseCustomizations + PubUsePythonTypes(codegenContext.runtimeConfig)
}
val DECORATORS = listOf(
@ -82,7 +81,7 @@ val DECORATORS = listOf(
)
// Combined codegen decorator for Python services.
class PythonServerCodegenDecorator : CombinedCodegenDecorator(DECORATORS) {
class PythonServerCodegenDecorator : CombinedCodegenDecorator<ServerCodegenContext>(DECORATORS) {
override val name: String = "PythonServerCodegenDecorator"
override val order: Byte = -1
}

View File

@ -12,7 +12,7 @@ import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.server.python.smithy.PythonServerCargoDependency
import software.amazon.smithy.rust.codegen.server.smithy.ServerCargoDependency
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.util.toSnakeCase
/**
@ -53,11 +53,11 @@ import software.amazon.smithy.rust.codegen.util.toSnakeCase
* that abstracts the processes / event loops / workers lifecycles.
*/
class PythonApplicationGenerator(
codegenContext: CodegenContext,
coreCodegenContext: CoreCodegenContext,
private val operations: List<OperationShape>,
) {
private val symbolProvider = codegenContext.symbolProvider
private val runtimeConfig = codegenContext.runtimeConfig
private val symbolProvider = coreCodegenContext.symbolProvider
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val codegenScope =
arrayOf(
"SmithyPython" to PythonServerCargoDependency.SmithyHttpServerPython(runtimeConfig).asType(),

View File

@ -14,7 +14,7 @@ import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.server.python.smithy.PythonServerCargoDependency
import software.amazon.smithy.rust.codegen.server.smithy.ServerCargoDependency
import software.amazon.smithy.rust.codegen.server.smithy.generators.ServerOperationHandlerGenerator
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.util.toSnakeCase
/**
@ -32,11 +32,11 @@ import software.amazon.smithy.rust.codegen.util.toSnakeCase
* To call a Python coroutine, the same happens, but scheduled in a `tokio::Future`.
*/
class PythonServerOperationHandlerGenerator(
codegenContext: CodegenContext,
coreCodegenContext: CoreCodegenContext,
private val operations: List<OperationShape>,
) : ServerOperationHandlerGenerator(codegenContext, operations) {
private val symbolProvider = codegenContext.symbolProvider
private val runtimeConfig = codegenContext.runtimeConfig
) : ServerOperationHandlerGenerator(coreCodegenContext, operations) {
private val symbolProvider = coreCodegenContext.symbolProvider
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val codegenScope =
arrayOf(
"SmithyPython" to PythonServerCargoDependency.SmithyHttpServerPython(runtimeConfig).asType(),

View File

@ -9,7 +9,7 @@ import software.amazon.smithy.model.shapes.OperationShape
import software.amazon.smithy.rust.codegen.rustlang.RustModule
import software.amazon.smithy.rust.codegen.rustlang.RustWriter
import software.amazon.smithy.rust.codegen.server.smithy.generators.ServerServiceGenerator
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RustCrate
import software.amazon.smithy.rust.codegen.smithy.generators.protocol.ProtocolGenerator
import software.amazon.smithy.rust.codegen.smithy.generators.protocol.ProtocolSupport
@ -26,7 +26,7 @@ class PythonServerServiceGenerator(
protocolGenerator: ProtocolGenerator,
protocolSupport: ProtocolSupport,
httpBindingResolver: HttpBindingResolver,
private val context: CodegenContext,
private val context: CoreCodegenContext,
) : ServerServiceGenerator(rustCrate, protocolGenerator, protocolSupport, httpBindingResolver, context) {
override fun renderCombinedErrors(writer: RustWriter, operation: OperationShape) {

View File

@ -11,9 +11,10 @@ import software.amazon.smithy.codegen.core.ReservedWordSymbolProvider
import software.amazon.smithy.model.Model
import software.amazon.smithy.model.shapes.ServiceShape
import software.amazon.smithy.rust.codegen.rustlang.RustReservedWordSymbolProvider
import software.amazon.smithy.rust.codegen.server.smithy.customizations.ServerRequiredCustomizations
import software.amazon.smithy.rust.codegen.smithy.BaseSymbolMetadataProvider
import software.amazon.smithy.rust.codegen.smithy.DefaultConfig
import software.amazon.smithy.rust.codegen.smithy.EventStreamSymbolProvider
import software.amazon.smithy.rust.codegen.smithy.ServerCodegenContext
import software.amazon.smithy.rust.codegen.smithy.StreamingShapeMetadataProvider
import software.amazon.smithy.rust.codegen.smithy.StreamingShapeSymbolProvider
import software.amazon.smithy.rust.codegen.smithy.SymbolVisitor
@ -35,12 +36,13 @@ class RustCodegenServerPlugin : SmithyBuildPlugin {
override fun execute(context: PluginContext) {
// Suppress extremely noisy logs about reserved words
Logger.getLogger(ReservedWordSymbolProvider::class.java.name).level = Level.OFF
// Discover [RustCodegenDecorators] on the classpath. [RustCodegenDecorator] return different types of
// customization. A customization is a function of:
// Discover [RustCodegenDecorators] on the classpath. [RustCodegenDecorator] returns different types of
// customizations. A customization is a function of:
// - location (e.g. the mutate section of an operation)
// - context (e.g. the of the operation)
// - writer: The active RustWriter at the given location
val codegenDecorator = CombinedCodegenDecorator.fromClasspath(context)
val codegenDecorator: CombinedCodegenDecorator<ServerCodegenContext> =
CombinedCodegenDecorator.fromClasspath(context, ServerRequiredCustomizations())
// ServerCodegenVisitor is the main driver of code generation that traverses the model and generates code
logger.info("Loaded plugin to generate pure Rust bindings for the server SSDK")
@ -57,7 +59,7 @@ class RustCodegenServerPlugin : SmithyBuildPlugin {
fun baseSymbolProvider(
model: Model,
serviceShape: ServiceShape,
symbolVisitorConfig: SymbolVisitorConfig = DefaultConfig
symbolVisitorConfig: SymbolVisitorConfig
) =
SymbolVisitor(model, serviceShape = serviceShape, config = symbolVisitorConfig)
// Generate different types for EventStream shapes (e.g. transcribe streaming)

View File

@ -19,11 +19,12 @@ import software.amazon.smithy.model.transform.ModelTransformer
import software.amazon.smithy.rust.codegen.server.smithy.generators.ServerEnumGenerator
import software.amazon.smithy.rust.codegen.server.smithy.generators.ServerServiceGenerator
import software.amazon.smithy.rust.codegen.server.smithy.protocols.ServerProtocolLoader
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreRustSettings
import software.amazon.smithy.rust.codegen.smithy.DefaultPublicModules
import software.amazon.smithy.rust.codegen.smithy.RustCrate
import software.amazon.smithy.rust.codegen.smithy.RustSettings
import software.amazon.smithy.rust.codegen.smithy.RustSymbolProvider
import software.amazon.smithy.rust.codegen.smithy.ServerCodegenContext
import software.amazon.smithy.rust.codegen.smithy.ServerRustSettings
import software.amazon.smithy.rust.codegen.smithy.SymbolVisitorConfig
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.generators.BuilderGenerator
@ -32,9 +33,7 @@ import software.amazon.smithy.rust.codegen.smithy.generators.StructureGenerator
import software.amazon.smithy.rust.codegen.smithy.generators.UnionGenerator
import software.amazon.smithy.rust.codegen.smithy.generators.implBlock
import software.amazon.smithy.rust.codegen.smithy.generators.protocol.ProtocolGenerator
import software.amazon.smithy.rust.codegen.smithy.letIf
import software.amazon.smithy.rust.codegen.smithy.protocols.ProtocolGeneratorFactory
import software.amazon.smithy.rust.codegen.smithy.transformers.AddErrorMessage
import software.amazon.smithy.rust.codegen.smithy.transformers.EventStreamNormalizer
import software.amazon.smithy.rust.codegen.smithy.transformers.OperationNormalizer
import software.amazon.smithy.rust.codegen.smithy.transformers.RecursiveShapeBoxer
@ -48,27 +47,29 @@ import java.util.logging.Logger
* Entrypoint for server-side code generation. This class will walk the in-memory model and
* generate all the needed types by calling the accept() function on the available shapes.
*/
open class ServerCodegenVisitor(context: PluginContext, private val codegenDecorator: RustCodegenDecorator) :
ShapeVisitor.Default<Unit>() {
private val fileManifest = context.fileManifest
open class ServerCodegenVisitor(
context: PluginContext,
private val codegenDecorator: RustCodegenDecorator<ServerCodegenContext>
) : ShapeVisitor.Default<Unit>() {
protected val logger = Logger.getLogger(javaClass.name)
protected val settings = ServerRustSettings.from(context.model, context.settings)
var model: Model
var protocolGeneratorFactory: ProtocolGeneratorFactory<ProtocolGenerator>
var protocolGenerator: ProtocolGenerator
var codegenContext: CodegenContext
var symbolProvider: RustSymbolProvider
var rustCrate: RustCrate
protected var symbolProvider: RustSymbolProvider
protected var rustCrate: RustCrate
private val fileManifest = context.fileManifest
protected var model: Model
protected var codegenContext: ServerCodegenContext
protected var protocolGeneratorFactory: ProtocolGeneratorFactory<ProtocolGenerator, ServerCodegenContext>
protected var protocolGenerator: ProtocolGenerator
init {
val symbolVisitorConfig =
SymbolVisitorConfig(
runtimeConfig = settings.runtimeConfig,
codegenConfig = settings.codegenConfig,
handleRequired = true
renameExceptions = false,
handleRequired = true,
handleRustBoxing = true,
)
val baseModel = baselineTransform(context.model)
val service = settings.getService(baseModel)
@ -86,7 +87,13 @@ open class ServerCodegenVisitor(context: PluginContext, private val codegenDecor
symbolProvider =
codegenDecorator.symbolProvider(generator.symbolProvider(model, baseProvider))
codegenContext = CodegenContext(model, symbolProvider, service, protocol, settings, target = CodegenTarget.SERVER)
codegenContext = ServerCodegenContext(
model,
symbolProvider,
service,
protocol,
settings,
)
rustCrate = RustCrate(context.fileManifest, symbolProvider, DefaultPublicModules, settings.codegenConfig)
protocolGenerator = protocolGeneratorFactory.buildProtocolGenerator(codegenContext)
@ -102,8 +109,6 @@ open class ServerCodegenVisitor(context: PluginContext, private val codegenDecor
.let { ModelTransformer.create().copyServiceErrorsToOperations(it, settings.getService(it)) }
// Add `Box<T>` to recursive shapes as necessary
.let(RecursiveShapeBoxer::transform)
// Normalize the `message` field on errors when enabled in settings (default: true)
.letIf(settings.codegenConfig.addMessageToErrors, AddErrorMessage::transform)
// Normalize operations by adding synthetic input and output shapes to every operation
.let(OperationNormalizer::transform)
// Drop unsupported event stream operations from the model
@ -114,7 +119,7 @@ open class ServerCodegenVisitor(context: PluginContext, private val codegenDecor
/**
* Execute code generation
*
* 1. Load the service from [RustSettings].
* 1. Load the service from [CoreRustSettings].
* 2. Traverse every shape in the closure of the service.
* 3. Loop through each shape and visit them (calling the override functions in this class)
* 4. Call finalization tasks specified by decorators.

View File

@ -1,85 +0,0 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package software.amazon.smithy.rust.codegen.server.smithy
import software.amazon.smithy.model.Model
import software.amazon.smithy.model.node.ObjectNode
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.rust.codegen.smithy.CODEGEN_SETTINGS
import software.amazon.smithy.rust.codegen.smithy.CodegenConfig
import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.smithy.RustSettings
import java.util.Optional
/**
* Configuration of codegen settings
*
* [renameExceptions]: Rename `Exception` to `Error` in the generated SDK
* [includeFluentClient]: Generate a `client` module in the generated SDK (currently the AWS SDK sets this to false
* and generates its own client)
*
* [addMessageToErrors]: Adds a `message` field automatically to all error shapes
* [formatTimeoutSeconds]: Timeout for running cargo fmt at the end of code generation
*/
data class ServerCodegenConfig(
val renameExceptions: Boolean = false,
val includeFluentClient: Boolean = false,
val addMessageToErrors: Boolean = false,
val formatTimeoutSeconds: Int = 20,
val debugMode: Boolean = false,
// TODO(EventStream): [CLEANUP] Remove this property when turning on Event Stream for all services
val eventStreamAllowList: Set<String> = emptySet(),
) {
companion object {
fun fromNode(node: Optional<ObjectNode>): CodegenConfig {
return if (node.isPresent) {
CodegenConfig.fromNode(node)
} else {
CodegenConfig(
false,
false,
false,
20,
debugMode = false,
emptySet()
)
}
}
}
}
/**
* Settings used by [RustCodegenPlugin]
*/
class ServerRustSettings(
val service: ShapeId,
val moduleName: String,
val moduleVersion: String,
val moduleAuthors: List<String>,
val moduleDescription: String?,
val moduleRepository: String?,
val runtimeConfig: RuntimeConfig,
val codegenConfig: CodegenConfig,
val license: String?,
val examplesUri: String? = null,
private val model: Model
) {
companion object {
/**
* Create settings from a configuration object node.
*
* @param model Model to infer the service from (if not explicitly set in config)
* @param config Config object to load
* @throws software.amazon.smithy.model.node.ExpectationNotMetException
* @return Returns the extracted settings
*/
fun from(model: Model, config: ObjectNode): RustSettings {
val codegenSettings = config.getObjectMember(CODEGEN_SETTINGS)
val codegenConfig = ServerCodegenConfig.fromNode(codegenSettings)
return RustSettings.fromCodegenConfig(model, config, codegenConfig)
}
}
}

View File

@ -13,6 +13,7 @@ import software.amazon.smithy.model.shapes.StructureShape
import software.amazon.smithy.model.traits.ErrorTrait
import software.amazon.smithy.model.traits.RequiredTrait
import software.amazon.smithy.model.transform.ModelTransformer
import software.amazon.smithy.rust.codegen.smithy.ServerCodegenContext
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
/**
@ -29,12 +30,12 @@ import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
* mkdir -p "$D" && echo "$C" > "$D/$F"
* ```
*/
class AddInternalServerErrorToInfallibleOperationsDecorator : RustCodegenDecorator {
class AddInternalServerErrorToInfallibleOperationsDecorator : RustCodegenDecorator<ServerCodegenContext> {
override val name: String = "AddInternalServerErrorToInfallibleOperations"
override val order: Byte = 0
override fun transformModel(service: ServiceShape, model: Model): Model =
addErrorShapeToModelOperations(service, model, { shape -> shape.errors.isEmpty() })
addErrorShapeToModelOperations(service, model) { shape -> shape.errors.isEmpty() }
}
/**
@ -55,16 +56,16 @@ class AddInternalServerErrorToInfallibleOperationsDecorator : RustCodegenDecorat
* mkdir -p "$D" && echo "$C" > "$D/$F"
* ```
*/
class AddInternalServerErrorToAllOperationsDecorator : RustCodegenDecorator {
class AddInternalServerErrorToAllOperationsDecorator : RustCodegenDecorator<ServerCodegenContext> {
override val name: String = "AddInternalServerErrorToAllOperations"
override val order: Byte = 0
override fun transformModel(service: ServiceShape, model: Model): Model =
addErrorShapeToModelOperations(service, model, { _ -> true })
addErrorShapeToModelOperations(service, model) { true }
}
fun addErrorShapeToModelOperations(service: ServiceShape, model: Model, opSelector: (OperationShape) -> Boolean): Model {
val errorShape = internalServerError(service.id.getNamespace())
val errorShape = internalServerError(service.id.namespace)
val modelShapes = model.toBuilder().addShapes(listOf(errorShape)).build()
return ModelTransformer.create().mapShapes(modelShapes) { shape ->
if (shape is OperationShape && opSelector(shape)) {
@ -75,7 +76,7 @@ fun addErrorShapeToModelOperations(service: ServiceShape, model: Model, opSelect
}
}
fun internalServerError(namespace: String): StructureShape =
private fun internalServerError(namespace: String): StructureShape =
StructureShape.builder().id("$namespace#InternalServerError")
.addTrait(ErrorTrait("server"))
.addMember(

View File

@ -0,0 +1,38 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package software.amazon.smithy.rust.codegen.server.smithy.customizations
import software.amazon.smithy.rust.codegen.rustlang.Feature
import software.amazon.smithy.rust.codegen.smithy.RustCrate
import software.amazon.smithy.rust.codegen.smithy.ServerCodegenContext
import software.amazon.smithy.rust.codegen.smithy.customizations.AllowLintsGenerator
import software.amazon.smithy.rust.codegen.smithy.customizations.CrateVersionGenerator
import software.amazon.smithy.rust.codegen.smithy.customizations.SmithyTypesPubUseGenerator
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.generators.LibRsCustomization
/**
* A set of customizations that are included in all protocols.
*
* This exists as a convenient place to gather these modifications, these are not true customizations.
*
* See [RequiredCustomizations] from the `rust-codegen` subproject for the client version of this decorator.
*/
class ServerRequiredCustomizations : RustCodegenDecorator<ServerCodegenContext> {
override val name: String = "ServerRequired"
override val order: Byte = -1
override fun libRsCustomizations(
codegenContext: ServerCodegenContext,
baseCustomizations: List<LibRsCustomization>
): List<LibRsCustomization> =
baseCustomizations + CrateVersionGenerator() + SmithyTypesPubUseGenerator(codegenContext.runtimeConfig) + AllowLintsGenerator()
override fun extras(codegenContext: ServerCodegenContext, rustCrate: RustCrate) {
// Add rt-tokio feature for `ByteStream::from_path`
rustCrate.mergeFeature(Feature("rt-tokio", true, listOf("aws-smithy-http/rt-tokio")))
}
}

View File

@ -14,7 +14,7 @@ import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.server.smithy.ServerCargoDependency
import software.amazon.smithy.rust.codegen.server.smithy.ServerRuntimeType
import software.amazon.smithy.rust.codegen.server.smithy.protocols.ServerHttpBoundProtocolGenerator
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.generators.error.errorSymbol
import software.amazon.smithy.rust.codegen.util.hasStreamingMember
@ -26,16 +26,16 @@ import software.amazon.smithy.rust.codegen.util.toPascalCase
* ServerOperationHandlerGenerator
*/
open class ServerOperationHandlerGenerator(
codegenContext: CodegenContext,
coreCodegenContext: CoreCodegenContext,
private val operations: List<OperationShape>,
) {
private val serverCrate = "aws_smithy_http_server"
private val service = codegenContext.serviceShape
private val model = codegenContext.model
private val protocol = codegenContext.protocol
private val symbolProvider = codegenContext.symbolProvider
private val service = coreCodegenContext.serviceShape
private val model = coreCodegenContext.model
private val protocol = coreCodegenContext.protocol
private val symbolProvider = coreCodegenContext.symbolProvider
private val operationNames = operations.map { symbolProvider.toSymbol(it).name }
private val runtimeConfig = codegenContext.runtimeConfig
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val codegenScope = arrayOf(
"AsyncTrait" to ServerCargoDependency.AsyncTrait.asType(),
"PinProjectLite" to ServerCargoDependency.PinProjectLite.asType(),

View File

@ -18,7 +18,7 @@ import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.server.smithy.ServerCargoDependency
import software.amazon.smithy.rust.codegen.server.smithy.ServerRuntimeType
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.protocols.HttpBindingResolver
import software.amazon.smithy.rust.codegen.util.dq
@ -28,15 +28,15 @@ import software.amazon.smithy.rust.codegen.util.toSnakeCase
* ServerOperationRegistryGenerator
*/
class ServerOperationRegistryGenerator(
codegenContext: CodegenContext,
coreCodegenContext: CoreCodegenContext,
private val httpBindingResolver: HttpBindingResolver,
private val operations: List<OperationShape>,
) {
private val protocol = codegenContext.protocol
private val symbolProvider = codegenContext.symbolProvider
private val serviceName = codegenContext.serviceShape.toShapeId().name
private val protocol = coreCodegenContext.protocol
private val symbolProvider = coreCodegenContext.symbolProvider
private val serviceName = coreCodegenContext.serviceShape.toShapeId().name
private val operationNames = operations.map { symbolProvider.toSymbol(it).name.toSnakeCase() }
private val runtimeConfig = codegenContext.runtimeConfig
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val codegenScope = arrayOf(
"Router" to ServerRuntimeType.Router(runtimeConfig),
"SmithyHttpServer" to ServerCargoDependency.SmithyHttpServer(runtimeConfig).asType(),

View File

@ -10,7 +10,7 @@ import software.amazon.smithy.model.shapes.OperationShape
import software.amazon.smithy.rust.codegen.rustlang.RustModule
import software.amazon.smithy.rust.codegen.rustlang.RustWriter
import software.amazon.smithy.rust.codegen.server.smithy.generators.protocol.ServerProtocolTestGenerator
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RustCrate
import software.amazon.smithy.rust.codegen.smithy.generators.protocol.ProtocolGenerator
import software.amazon.smithy.rust.codegen.smithy.generators.protocol.ProtocolSupport
@ -27,10 +27,10 @@ open class ServerServiceGenerator(
private val protocolGenerator: ProtocolGenerator,
private val protocolSupport: ProtocolSupport,
private val httpBindingResolver: HttpBindingResolver,
private val context: CodegenContext,
private val coreCodegenContext: CoreCodegenContext,
) {
private val index = TopDownIndex.of(context.model)
protected val operations = index.getContainedOperations(context.serviceShape).sortedBy { it.id }
private val index = TopDownIndex.of(coreCodegenContext.model)
protected val operations = index.getContainedOperations(coreCodegenContext.serviceShape).sortedBy { it.id }
/**
* Render Service Specific code. Code will end up in different files via [useShapeWriter]. See `SymbolVisitor.kt`
@ -43,7 +43,7 @@ open class ServerServiceGenerator(
operationWriter,
operation,
)
ServerProtocolTestGenerator(context, protocolSupport, operation, operationWriter)
ServerProtocolTestGenerator(coreCodegenContext, protocolSupport, operation, operationWriter)
.render()
}
if (operation.errors.isNotEmpty()) {
@ -66,16 +66,16 @@ open class ServerServiceGenerator(
// Render combined errors.
open fun renderCombinedErrors(writer: RustWriter, operation: OperationShape) {
ServerCombinedErrorGenerator(context.model, context.symbolProvider, operation).render(writer)
ServerCombinedErrorGenerator(coreCodegenContext.model, coreCodegenContext.symbolProvider, operation).render(writer)
}
// Render operations handler.
open fun renderOperationHandler(writer: RustWriter, operations: List<OperationShape>) {
ServerOperationHandlerGenerator(context, operations).render(writer)
ServerOperationHandlerGenerator(coreCodegenContext, operations).render(writer)
}
// Render operations registry.
private fun renderOperationRegistry(writer: RustWriter, operations: List<OperationShape>) {
ServerOperationRegistryGenerator(context, httpBindingResolver, operations).render(writer)
ServerOperationRegistryGenerator(coreCodegenContext, httpBindingResolver, operations).render(writer)
}
}

View File

@ -7,7 +7,7 @@ package software.amazon.smithy.rust.codegen.server.smithy.generators.http
import software.amazon.smithy.model.shapes.OperationShape
import software.amazon.smithy.rust.codegen.rustlang.RustWriter
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.generators.http.HttpBindingGenerator
import software.amazon.smithy.rust.codegen.smithy.generators.http.HttpMessageType
@ -16,10 +16,10 @@ import software.amazon.smithy.rust.codegen.smithy.protocols.Protocol
class ServerRequestBindingGenerator(
protocol: Protocol,
codegenContext: CodegenContext,
coreCodegenContext: CoreCodegenContext,
operationShape: OperationShape
) {
private val httpBindingGenerator = HttpBindingGenerator(protocol, codegenContext, operationShape)
private val httpBindingGenerator = HttpBindingGenerator(protocol, coreCodegenContext, operationShape)
fun generateDeserializeHeaderFn(binding: HttpBindingDescriptor): RuntimeType =
httpBindingGenerator.generateDeserializeHeaderFn(binding)

View File

@ -7,7 +7,7 @@ package software.amazon.smithy.rust.codegen.server.smithy.generators.http
import software.amazon.smithy.model.shapes.OperationShape
import software.amazon.smithy.model.shapes.Shape
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.generators.http.HttpBindingGenerator
import software.amazon.smithy.rust.codegen.smithy.generators.http.HttpMessageType
@ -15,10 +15,10 @@ import software.amazon.smithy.rust.codegen.smithy.protocols.Protocol
class ServerResponseBindingGenerator(
protocol: Protocol,
codegenContext: CodegenContext,
coreCodegenContext: CoreCodegenContext,
operationShape: OperationShape
) {
private val httpBindingGenerator = HttpBindingGenerator(protocol, codegenContext, operationShape)
private val httpBindingGenerator = HttpBindingGenerator(protocol, coreCodegenContext, operationShape)
fun generateAddHeadersFn(shape: Shape): RuntimeType? =
httpBindingGenerator.generateAddHeadersFn(shape, HttpMessageType.RESPONSE)

View File

@ -34,7 +34,7 @@ import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.withBlock
import software.amazon.smithy.rust.codegen.server.smithy.ServerCargoDependency
import software.amazon.smithy.rust.codegen.server.smithy.protocols.ServerHttpBoundProtocolGenerator
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.generators.CodegenTarget
import software.amazon.smithy.rust.codegen.smithy.generators.Instantiator
@ -56,32 +56,32 @@ import kotlin.reflect.KFunction1
* Generate protocol tests for an operation
*/
class ServerProtocolTestGenerator(
private val codegenContext: CodegenContext,
private val coreCodegenContext: CoreCodegenContext,
private val protocolSupport: ProtocolSupport,
private val operationShape: OperationShape,
private val writer: RustWriter
) {
private val logger = Logger.getLogger(javaClass.name)
private val model = codegenContext.model
private val inputShape = operationShape.inputShape(codegenContext.model)
private val outputShape = operationShape.outputShape(codegenContext.model)
private val symbolProvider = codegenContext.symbolProvider
private val model = coreCodegenContext.model
private val inputShape = operationShape.inputShape(coreCodegenContext.model)
private val outputShape = operationShape.outputShape(coreCodegenContext.model)
private val symbolProvider = coreCodegenContext.symbolProvider
private val operationSymbol = symbolProvider.toSymbol(operationShape)
private val operationIndex = OperationIndex.of(codegenContext.model)
private val operationIndex = OperationIndex.of(coreCodegenContext.model)
private val operationImplementationName = "${operationSymbol.name}${ServerHttpBoundProtocolGenerator.OPERATION_OUTPUT_WRAPPER_SUFFIX}"
private val operationErrorName = "crate::error::${operationSymbol.name}Error"
private val instantiator = with(codegenContext) {
private val instantiator = with(coreCodegenContext) {
Instantiator(symbolProvider, model, runtimeConfig, CodegenTarget.SERVER)
}
private val codegenScope = arrayOf(
"Bytes" to RuntimeType.Bytes,
"SmithyHttp" to CargoDependency.SmithyHttp(codegenContext.runtimeConfig).asType(),
"SmithyHttp" to CargoDependency.SmithyHttp(coreCodegenContext.runtimeConfig).asType(),
"Http" to CargoDependency.Http.asType(),
"Hyper" to CargoDependency.Hyper.asType(),
"SmithyHttpServer" to ServerCargoDependency.SmithyHttpServer(codegenContext.runtimeConfig).asType(),
"SmithyHttpServer" to ServerCargoDependency.SmithyHttpServer(coreCodegenContext.runtimeConfig).asType(),
"AssertEq" to CargoDependency.PrettyAssertions.asType().member("assert_eq!")
)
@ -163,7 +163,7 @@ class ServerProtocolTestGenerator(
private fun List<TestCase>.filterMatching(): List<TestCase> {
return if (RunOnly.isNullOrEmpty()) {
this.filter { testCase ->
testCase.protocol == codegenContext.protocol &&
testCase.protocol == coreCodegenContext.protocol &&
!DisableTests.contains(testCase.id)
}
} else {
@ -177,7 +177,7 @@ class ServerProtocolTestGenerator(
private fun List<TestCase>.fixBroken(): List<TestCase> = this.map {
when (it) {
is TestCase.RequestTest -> {
val howToFixIt = BrokenRequestTests[Pair(codegenContext.serviceShape.id.toString(), it.id)]
val howToFixIt = BrokenRequestTests[Pair(coreCodegenContext.serviceShape.id.toString(), it.id)]
if (howToFixIt == null) {
it
} else {
@ -186,7 +186,7 @@ class ServerProtocolTestGenerator(
}
}
is TestCase.ResponseTest -> {
val howToFixIt = BrokenResponseTests[Pair(codegenContext.serviceShape.id.toString(), it.id)]
val howToFixIt = BrokenResponseTests[Pair(coreCodegenContext.serviceShape.id.toString(), it.id)]
if (howToFixIt == null) {
it
} else {
@ -259,7 +259,7 @@ class ServerProtocolTestGenerator(
}
private fun expectFail(testCase: TestCase): Boolean = ExpectFail.find {
it.id == testCase.id && it.testType == testCase.testType && it.service == codegenContext.serviceShape.id.toString()
it.id == testCase.id && it.testType == testCase.testType && it.service == coreCodegenContext.serviceShape.id.toString()
} != null
/**
@ -393,8 +393,8 @@ class ServerProtocolTestGenerator(
// A streaming shape does not implement `PartialEq`, so we have to iterate over the input shape's members
// and handle the equality assertion separately.
for (member in inputShape.members()) {
val memberName = codegenContext.symbolProvider.toMemberName(member)
if (member.isStreaming(codegenContext.model)) {
val memberName = coreCodegenContext.symbolProvider.toMemberName(member)
if (member.isStreaming(coreCodegenContext.model)) {
rustWriter.rustTemplate(
"""
#{AssertEq}(
@ -422,11 +422,11 @@ class ServerProtocolTestGenerator(
// TODO(https://github.com/awslabs/smithy-rs/issues/1147) Handle the case of nested floating point members.
if (hasFloatingPointMembers) {
for (member in inputShape.members()) {
val memberName = codegenContext.symbolProvider.toMemberName(member)
when (codegenContext.model.expectShape(member.target)) {
val memberName = coreCodegenContext.symbolProvider.toMemberName(member)
when (coreCodegenContext.model.expectShape(member.target)) {
is DoubleShape, is FloatShape -> {
rustWriter.addUseImports(
RuntimeType.ProtocolTestHelper(codegenContext.runtimeConfig, "FloatEquals").toSymbol()
RuntimeType.ProtocolTestHelper(coreCodegenContext.runtimeConfig, "FloatEquals").toSymbol()
)
rustWriter.rust(
"""
@ -518,8 +518,8 @@ class ServerProtocolTestGenerator(
"#T(&body, ${
rustWriter.escape(body).dq()
}, #T::from(${(mediaType ?: "unknown").dq()}))",
RuntimeType.ProtocolTestHelper(codegenContext.runtimeConfig, "validate_body"),
RuntimeType.ProtocolTestHelper(codegenContext.runtimeConfig, "MediaType")
RuntimeType.ProtocolTestHelper(coreCodegenContext.runtimeConfig, "validate_body"),
RuntimeType.ProtocolTestHelper(coreCodegenContext.runtimeConfig, "MediaType")
)
}
}
@ -588,7 +588,7 @@ class ServerProtocolTestGenerator(
assertOk(rustWriter) {
write(
"#T($actualExpression, $variableName)",
RuntimeType.ProtocolTestHelper(codegenContext.runtimeConfig, "validate_headers")
RuntimeType.ProtocolTestHelper(coreCodegenContext.runtimeConfig, "validate_headers")
)
}
}
@ -609,7 +609,7 @@ class ServerProtocolTestGenerator(
assertOk(rustWriter) {
write(
"#T($actualExpression, $expectedVariableName)",
RuntimeType.ProtocolTestHelper(codegenContext.runtimeConfig, checkFunction)
RuntimeType.ProtocolTestHelper(coreCodegenContext.runtimeConfig, checkFunction)
)
}
}
@ -619,7 +619,7 @@ class ServerProtocolTestGenerator(
* for pretty prettying protocol test helper results
*/
private fun assertOk(rustWriter: RustWriter, inner: RustWriter.() -> Unit) {
rustWriter.write("#T(", RuntimeType.ProtocolTestHelper(codegenContext.runtimeConfig, "assert_ok"))
rustWriter.write("#T(", RuntimeType.ProtocolTestHelper(coreCodegenContext.runtimeConfig, "assert_ok"))
inner(rustWriter)
rustWriter.write(");")
}

View File

@ -12,7 +12,8 @@ import software.amazon.smithy.rust.codegen.rustlang.Writable
import software.amazon.smithy.rust.codegen.rustlang.escape
import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.ServerCodegenContext
import software.amazon.smithy.rust.codegen.smithy.generators.protocol.ProtocolSupport
import software.amazon.smithy.rust.codegen.smithy.protocols.AwsJson
import software.amazon.smithy.rust.codegen.smithy.protocols.AwsJsonVersion
@ -30,10 +31,11 @@ import software.amazon.smithy.rust.codegen.util.hasTrait
* AwsJson 1.0 and 1.1 server-side protocol factory. This factory creates the [ServerHttpBoundProtocolGenerator]
* with AwsJson specific configurations.
*/
class ServerAwsJsonFactory(private val version: AwsJsonVersion) : ProtocolGeneratorFactory<ServerHttpBoundProtocolGenerator> {
override fun protocol(codegenContext: CodegenContext): Protocol = ServerAwsJson(codegenContext, version)
class ServerAwsJsonFactory(private val version: AwsJsonVersion) :
ProtocolGeneratorFactory<ServerHttpBoundProtocolGenerator, ServerCodegenContext> {
override fun protocol(codegenContext: ServerCodegenContext): Protocol = ServerAwsJson(codegenContext, version)
override fun buildProtocolGenerator(codegenContext: CodegenContext): ServerHttpBoundProtocolGenerator =
override fun buildProtocolGenerator(codegenContext: ServerCodegenContext): ServerHttpBoundProtocolGenerator =
ServerHttpBoundProtocolGenerator(codegenContext, protocol(codegenContext))
override fun transformModel(model: Model): Model = model
@ -81,17 +83,17 @@ class ServerAwsJsonError(private val awsJsonVersion: AwsJsonVersion) : JsonCusto
* customizes [JsonSerializerGenerator] to add this functionality.
*/
class ServerAwsJsonSerializerGenerator(
private val codegenContext: CodegenContext,
private val coreCodegenContext: CoreCodegenContext,
private val httpBindingResolver: HttpBindingResolver,
private val awsJsonVersion: AwsJsonVersion,
private val jsonSerializerGenerator: JsonSerializerGenerator =
JsonSerializerGenerator(codegenContext, httpBindingResolver, ::awsJsonFieldName, customizations = listOf(ServerAwsJsonError(awsJsonVersion)))
JsonSerializerGenerator(coreCodegenContext, httpBindingResolver, ::awsJsonFieldName, customizations = listOf(ServerAwsJsonError(awsJsonVersion)))
) : StructuredDataSerializerGenerator by jsonSerializerGenerator
class ServerAwsJson(
private val codegenContext: CodegenContext,
private val coreCodegenContext: CoreCodegenContext,
private val awsJsonVersion: AwsJsonVersion
) : AwsJson(codegenContext, awsJsonVersion) {
) : AwsJson(coreCodegenContext, awsJsonVersion) {
override fun structuredDataSerializer(operationShape: OperationShape): StructuredDataSerializerGenerator =
ServerAwsJsonSerializerGenerator(codegenContext, httpBindingResolver, awsJsonVersion)
ServerAwsJsonSerializerGenerator(coreCodegenContext, httpBindingResolver, awsJsonVersion)
}

View File

@ -41,8 +41,8 @@ import software.amazon.smithy.rust.codegen.server.smithy.ServerCargoDependency
import software.amazon.smithy.rust.codegen.server.smithy.ServerRuntimeType
import software.amazon.smithy.rust.codegen.server.smithy.generators.http.ServerRequestBindingGenerator
import software.amazon.smithy.rust.codegen.server.smithy.generators.http.ServerResponseBindingGenerator
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.ServerCodegenContext
import software.amazon.smithy.rust.codegen.smithy.extractSymbolFromOption
import software.amazon.smithy.rust.codegen.smithy.generators.StructureGenerator
import software.amazon.smithy.rust.codegen.smithy.generators.builderSymbol
@ -78,7 +78,7 @@ import java.util.logging.Logger
* See `ServerRestJsonFactory.kt` for more info.
*/
class ServerHttpBoundProtocolGenerator(
codegenContext: CodegenContext,
codegenContext: ServerCodegenContext,
protocol: Protocol,
) : ProtocolGenerator(
codegenContext,
@ -104,7 +104,7 @@ class ServerHttpBoundProtocolGenerator(
* non-streaming types.
*/
private class ServerHttpBoundProtocolTraitImplGenerator(
private val codegenContext: CodegenContext,
private val codegenContext: ServerCodegenContext,
private val protocol: Protocol,
) : ProtocolTraitImplGenerator {
private val logger = Logger.getLogger(javaClass.name)

View File

@ -15,6 +15,7 @@ import software.amazon.smithy.model.knowledge.ServiceIndex
import software.amazon.smithy.model.shapes.ServiceShape
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.model.traits.Trait
import software.amazon.smithy.rust.codegen.smithy.ServerCodegenContext
import software.amazon.smithy.rust.codegen.smithy.generators.protocol.ProtocolGenerator
import software.amazon.smithy.rust.codegen.smithy.protocols.AwsJsonVersion
import software.amazon.smithy.rust.codegen.smithy.protocols.ProtocolGeneratorFactory
@ -23,11 +24,11 @@ import software.amazon.smithy.rust.codegen.smithy.protocols.ProtocolMap
/*
* Protocol dispatcher, responsible for protocol selection.
*/
class ServerProtocolLoader(private val supportedProtocols: ProtocolMap) {
class ServerProtocolLoader(private val supportedProtocols: ProtocolMap<ServerCodegenContext>) {
fun protocolFor(
model: Model,
serviceShape: ServiceShape
): Pair<ShapeId, ProtocolGeneratorFactory<ProtocolGenerator>> {
): Pair<ShapeId, ProtocolGeneratorFactory<ProtocolGenerator, ServerCodegenContext>> {
val protocols: MutableMap<ShapeId, Trait> = ServiceIndex.of(model).getProtocols(serviceShape)
val matchingProtocols =
protocols.keys.mapNotNull { protocolId -> supportedProtocols[protocolId]?.let { protocolId to it } }

View File

@ -6,7 +6,7 @@
package software.amazon.smithy.rust.codegen.server.smithy.protocols
import software.amazon.smithy.model.Model
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ServerCodegenContext
import software.amazon.smithy.rust.codegen.smithy.generators.protocol.ProtocolSupport
import software.amazon.smithy.rust.codegen.smithy.protocols.Protocol
import software.amazon.smithy.rust.codegen.smithy.protocols.ProtocolGeneratorFactory
@ -16,10 +16,10 @@ import software.amazon.smithy.rust.codegen.smithy.protocols.RestJson
* RestJson1 server-side protocol factory. This factory creates the [ServerHttpProtocolGenerator]
* with RestJson1 specific configurations.
*/
class ServerRestJsonFactory : ProtocolGeneratorFactory<ServerHttpBoundProtocolGenerator> {
override fun protocol(codegenContext: CodegenContext): Protocol = RestJson(codegenContext)
class ServerRestJsonFactory : ProtocolGeneratorFactory<ServerHttpBoundProtocolGenerator, ServerCodegenContext> {
override fun protocol(codegenContext: ServerCodegenContext): Protocol = RestJson(codegenContext)
override fun buildProtocolGenerator(codegenContext: CodegenContext): ServerHttpBoundProtocolGenerator =
override fun buildProtocolGenerator(codegenContext: ServerCodegenContext): ServerHttpBoundProtocolGenerator =
ServerHttpBoundProtocolGenerator(codegenContext, RestJson(codegenContext))
override fun transformModel(model: Model): Model = model

View File

@ -6,7 +6,7 @@
package software.amazon.smithy.rust.codegen.server.smithy.protocols
import software.amazon.smithy.model.Model
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ServerCodegenContext
import software.amazon.smithy.rust.codegen.smithy.generators.protocol.ProtocolSupport
import software.amazon.smithy.rust.codegen.smithy.protocols.Protocol
import software.amazon.smithy.rust.codegen.smithy.protocols.ProtocolGeneratorFactory
@ -16,10 +16,10 @@ import software.amazon.smithy.rust.codegen.smithy.protocols.RestXml
* RestXml server-side protocol factory. This factory creates the [ServerHttpProtocolGenerator]
* with RestXml specific configurations.
*/
class ServerRestXmlFactory : ProtocolGeneratorFactory<ServerHttpBoundProtocolGenerator> {
override fun protocol(codegenContext: CodegenContext): Protocol = RestXml(codegenContext)
class ServerRestXmlFactory : ProtocolGeneratorFactory<ServerHttpBoundProtocolGenerator, ServerCodegenContext> {
override fun protocol(codegenContext: ServerCodegenContext): Protocol = RestXml(codegenContext)
override fun buildProtocolGenerator(codegenContext: CodegenContext): ServerHttpBoundProtocolGenerator =
override fun buildProtocolGenerator(codegenContext: ServerCodegenContext): ServerHttpBoundProtocolGenerator =
ServerHttpBoundProtocolGenerator(codegenContext, RestXml(codegenContext))
override fun transformModel(model: Model): Model = model

View File

@ -8,26 +8,22 @@ package software.amazon.smithy.rust.codegen.server.smithy.testutil
import software.amazon.smithy.model.Model
import software.amazon.smithy.model.shapes.ServiceShape
import software.amazon.smithy.rust.codegen.server.smithy.RustCodegenServerPlugin
import software.amazon.smithy.rust.codegen.smithy.CodegenConfig
import software.amazon.smithy.rust.codegen.smithy.RustSymbolProvider
import software.amazon.smithy.rust.codegen.smithy.SymbolVisitorConfig
import software.amazon.smithy.rust.codegen.testutil.TestRuntimeConfig
// These are the settings we default to if the user does not override them in their `smithy-build.json`.
val ServerTestSymbolVisitorConfig = SymbolVisitorConfig(
runtimeConfig = TestRuntimeConfig,
// These are the settings we default to if the user does not override them in their `smithy-build.json`.
codegenConfig = CodegenConfig(
renameExceptions = false,
includeFluentClient = false,
addMessageToErrors = false,
formatTimeoutSeconds = 20,
eventStreamAllowList = emptySet()
),
renameExceptions = false,
handleRustBoxing = true,
handleRequired = true
)
fun serverTestSymbolProvider(model: Model, serviceShape: ServiceShape? = null): RustSymbolProvider =
fun serverTestSymbolProvider(
model: Model,
serviceShape: ServiceShape? = null,
): RustSymbolProvider =
RustCodegenServerPlugin.baseSymbolProvider(
model,
serviceShape ?: ServiceShape.builder().version("test").id("test#Service").build(),

View File

@ -0,0 +1,27 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package software.amazon.smithy.rust.codegen.smithy
import software.amazon.smithy.model.Model
import software.amazon.smithy.model.shapes.ServiceShape
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.rust.codegen.smithy.generators.CodegenTarget
/**
* [ClientCodegenContext] contains code-generation context that is _specific_ to the [RustCodegenPlugin] plugin
* from the `rust-codegen` subproject.
*
* It inherits from [CoreCodegenContext], which contains code-generation context that is common to _all_ smithy-rs plugins.
*/
data class ClientCodegenContext(
override val model: Model,
override val symbolProvider: RustSymbolProvider,
override val serviceShape: ServiceShape,
override val protocol: ShapeId,
override val settings: ClientRustSettings,
) : CoreCodegenContext(
model, symbolProvider, serviceShape, protocol, settings, CodegenTarget.CLIENT
)

View File

@ -0,0 +1,109 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package software.amazon.smithy.rust.codegen.smithy
import software.amazon.smithy.model.Model
import software.amazon.smithy.model.node.ObjectNode
import software.amazon.smithy.model.shapes.ShapeId
import java.util.Optional
/**
* [ClientRustSettings] and [ClientCodegenConfig] classes.
*
* These are specializations of [RustSettings] and [CodegenConfig] for the `rust-codegen` client Smithy plugin. Refer
* to the documentation of those for the inherited properties.
*/
/**
* Settings used by [RustCodegenPlugin].
*/
data class ClientRustSettings(
override val service: ShapeId,
override val moduleName: String,
override val moduleVersion: String,
override val moduleAuthors: List<String>,
override val moduleDescription: String?,
override val moduleRepository: String?,
override val runtimeConfig: RuntimeConfig,
override val codegenConfig: ClientCodegenConfig,
override val license: String?,
override val examplesUri: String?,
override val customizationConfig: ObjectNode?
) : CoreRustSettings(
service,
moduleName,
moduleVersion,
moduleAuthors,
moduleDescription,
moduleRepository,
runtimeConfig,
codegenConfig,
license,
examplesUri,
customizationConfig
) {
companion object {
fun from(model: Model, config: ObjectNode): ClientRustSettings {
val coreRustSettings = CoreRustSettings.from(model, config)
val codegenSettingsNode = config.getObjectMember(CODEGEN_SETTINGS)
val coreCodegenConfig = CoreCodegenConfig.fromNode(codegenSettingsNode)
return ClientRustSettings(
service = coreRustSettings.service,
moduleName = coreRustSettings.moduleName,
moduleVersion = coreRustSettings.moduleVersion,
moduleAuthors = coreRustSettings.moduleAuthors,
moduleDescription = coreRustSettings.moduleDescription,
moduleRepository = coreRustSettings.moduleRepository,
runtimeConfig = coreRustSettings.runtimeConfig,
codegenConfig = ClientCodegenConfig.fromCodegenConfigAndNode(coreCodegenConfig, codegenSettingsNode),
license = coreRustSettings.license,
examplesUri = coreRustSettings.examplesUri,
customizationConfig = coreRustSettings.customizationConfig
)
}
}
}
/**
* [renameExceptions]: Rename `Exception` to `Error` in the generated SDK
* [includeFluentClient]: Generate a `client` module in the generated SDK (currently the AWS SDK sets this to `false`
* and generates its own client)
* [addMessageToErrors]: Adds a `message` field automatically to all error shapes
*/
data class ClientCodegenConfig(
override val formatTimeoutSeconds: Int = defaultFormatTimeoutSeconds,
override val debugMode: Boolean = defaultDebugMode,
override val eventStreamAllowList: Set<String> = defaultEventStreamAllowList,
val renameExceptions: Boolean = defaultRenameExceptions,
val includeFluentClient: Boolean = defaultIncludeFluentClient,
val addMessageToErrors: Boolean = defaultAddMessageToErrors,
) : CoreCodegenConfig(
formatTimeoutSeconds, debugMode, eventStreamAllowList
) {
companion object {
private const val defaultRenameExceptions = true
private const val defaultIncludeFluentClient = true
private const val defaultAddMessageToErrors = true
fun fromCodegenConfigAndNode(coreCodegenConfig: CoreCodegenConfig, node: Optional<ObjectNode>) =
if (node.isPresent) {
ClientCodegenConfig(
formatTimeoutSeconds = coreCodegenConfig.formatTimeoutSeconds,
debugMode = coreCodegenConfig.debugMode,
eventStreamAllowList = coreCodegenConfig.eventStreamAllowList,
renameExceptions = node.get().getBooleanMemberOrDefault("renameErrors", defaultRenameExceptions),
includeFluentClient = node.get().getBooleanMemberOrDefault("includeFluentClient", defaultIncludeFluentClient),
addMessageToErrors = node.get().getBooleanMemberOrDefault("addMessageToErrors", defaultAddMessageToErrors),
)
} else {
ClientCodegenConfig(
formatTimeoutSeconds = coreCodegenConfig.formatTimeoutSeconds,
debugMode = coreCodegenConfig.debugMode,
eventStreamAllowList = coreCodegenConfig.eventStreamAllowList,
)
}
}
}

View File

@ -1,72 +0,0 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package software.amazon.smithy.rust.codegen.smithy
import software.amazon.smithy.model.Model
import software.amazon.smithy.model.shapes.ServiceShape
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.rust.codegen.smithy.generators.CodegenTarget
/**
* Configuration needed to generate the client for a given Service<->Protocol pair
*/
data class CodegenContext(
/**
* The smithy model.
*
* Note: This model may or not be pruned to the given service closure, so ensure that `serviceShape` is used as
* an entry point.
*/
val model: Model,
val symbolProvider: RustSymbolProvider,
/**
* Configuration of the runtime package:
* - Where are the runtime crates (smithy-*) located on the file system? Or are they versioned?
* - What are they called?
*/
val runtimeConfig: RuntimeConfig,
/**
* Entrypoint service shape for code generation
*/
val serviceShape: ServiceShape,
/**
* Smithy Protocol to generate, e.g. RestJson1
*/
val protocol: ShapeId,
/**
* Settings loaded from smithy-build.json
*/
val settings: RustSettings,
/**
* Server vs. Client codegen
*
* Some settings are dependent on whether server vs. client codegen is being invoked.
*/
val target: CodegenTarget,
) {
constructor(
model: Model,
symbolProvider: RustSymbolProvider,
serviceShape: ServiceShape,
protocol: ShapeId,
settings: RustSettings,
target: CodegenTarget,
) : this(model, symbolProvider, settings.runtimeConfig, serviceShape, protocol, settings, target)
/**
* The name of the cargo crate to generate e.g. `aws-sdk-s3`
* This is loaded from the smithy-build.json during codegen.
*/
val moduleName: String by lazy { settings.moduleName }
/**
* A moduleName for a crate uses kebab-case. When you want to `use` a crate in Rust code,
* it must be in snake-case. Call this method to get this crate's name in snake-case.
*/
fun moduleUseName(): String {
return this.moduleName.replace("-", "_")
}
}

View File

@ -47,9 +47,9 @@ open class RustCrate(
* private as well as any other metadata. [baseModules] enables configuring this. See [DefaultPublicModules].
*/
baseModules: Map<String, RustModule>,
codegenConfig: CodegenConfig
coreCodegenConfig: CoreCodegenConfig
) {
private val inner = WriterDelegator(fileManifest, symbolProvider, RustWriter.factory(codegenConfig.debugMode))
private val inner = WriterDelegator(fileManifest, symbolProvider, RustWriter.factory(coreCodegenConfig.debugMode))
private val modules: MutableMap<String, RustModule> = baseModules.toMutableMap()
private val features: MutableSet<Feature> = mutableSetOf()
@ -87,7 +87,7 @@ open class RustCrate(
* This is also where inline dependencies are actually reified and written, potentially recursively.
*/
fun finalize(
settings: RustSettings,
settings: CoreRustSettings,
model: Model,
manifestCustomizations: ManifestCustomizations,
libRsCustomizations: List<LibRsCustomization>,
@ -167,7 +167,7 @@ val DefaultPublicModules = setOf(
* - generating (and writing) a Cargo.toml based on the settings & the required dependencies
*/
fun WriterDelegator<RustWriter>.finalize(
settings: RustSettings,
settings: CoreRustSettings,
model: Model,
manifestCustomizations: ManifestCustomizations,
libRsCustomizations: List<LibRsCustomization>,

View File

@ -18,7 +18,6 @@ import software.amazon.smithy.model.traits.EnumTrait
import software.amazon.smithy.model.transform.ModelTransformer
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.generators.BuilderGenerator
import software.amazon.smithy.rust.codegen.smithy.generators.CodegenTarget
import software.amazon.smithy.rust.codegen.smithy.generators.EnumGenerator
import software.amazon.smithy.rust.codegen.smithy.generators.ServiceGenerator
import software.amazon.smithy.rust.codegen.smithy.generators.StructureGenerator
@ -42,41 +41,46 @@ import java.util.logging.Logger
/**
* Base Entrypoint for Code generation
*/
class CodegenVisitor(context: PluginContext, private val codegenDecorator: RustCodegenDecorator) :
class CodegenVisitor(context: PluginContext, private val codegenDecorator: RustCodegenDecorator<ClientCodegenContext>) :
ShapeVisitor.Default<Unit>() {
private val logger = Logger.getLogger(javaClass.name)
private val settings = RustSettings.from(context.model, context.settings)
private val settings = ClientRustSettings.from(context.model, context.settings)
private val symbolProvider: RustSymbolProvider
private val rustCrate: RustCrate
private val fileManifest = context.fileManifest
private val model: Model
private val codegenContext: CodegenContext
private val protocolGenerator: ProtocolGeneratorFactory<ProtocolGenerator>
private val httpGenerator: ProtocolGenerator
private val codegenContext: ClientCodegenContext
private val protocolGeneratorFactory: ProtocolGeneratorFactory<ProtocolGenerator, ClientCodegenContext>
private val protocolGenerator: ProtocolGenerator
init {
val symbolVisitorConfig =
SymbolVisitorConfig(runtimeConfig = settings.runtimeConfig, codegenConfig = settings.codegenConfig)
SymbolVisitorConfig(
runtimeConfig = settings.runtimeConfig,
renameExceptions = settings.codegenConfig.renameExceptions,
handleRequired = false,
handleRustBoxing = true,
)
val baseModel = baselineTransform(context.model)
val service = settings.getService(baseModel)
val (protocol, generator) = ProtocolLoader(
codegenDecorator.protocols(service.id, ProtocolLoader.DefaultProtocols)
).protocolFor(context.model, service)
protocolGenerator = generator
protocolGeneratorFactory = generator
model = generator.transformModel(codegenDecorator.transformModel(service, baseModel))
val baseProvider = RustCodegenPlugin.baseSymbolProvider(model, service, symbolVisitorConfig)
symbolProvider = codegenDecorator.symbolProvider(generator.symbolProvider(model, baseProvider))
codegenContext = CodegenContext(model, symbolProvider, service, protocol, settings, target = CodegenTarget.CLIENT)
codegenContext = ClientCodegenContext(model, symbolProvider, service, protocol, settings)
rustCrate = RustCrate(
context.fileManifest,
symbolProvider,
DefaultPublicModules,
codegenContext.settings.codegenConfig
)
httpGenerator = protocolGenerator.buildProtocolGenerator(codegenContext)
protocolGenerator = protocolGeneratorFactory.buildProtocolGenerator(codegenContext)
}
/**
@ -147,8 +151,8 @@ class CodegenVisitor(context: PluginContext, private val codegenDecorator: RustC
override fun serviceShape(shape: ServiceShape) {
ServiceGenerator(
rustCrate,
httpGenerator,
protocolGenerator.support(),
protocolGenerator,
protocolGeneratorFactory.support(),
codegenContext,
codegenDecorator
).render()

View File

@ -0,0 +1,83 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package software.amazon.smithy.rust.codegen.smithy
import software.amazon.smithy.model.Model
import software.amazon.smithy.model.shapes.ServiceShape
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.rust.codegen.smithy.generators.CodegenTarget
/**
* [CoreCodegenContext] contains code-generation context that is _common to all_ smithy-rs plugins.
*
* Code-generation context is pervasive read-only global data that gets passed around to the generators.
*
* If your data is specific to the `rust-codegen` client plugin, put it in [ClientCodegenContext] instead.
* If your data is specific to the `rust-server-codegen` server plugin, put it in [ServerCodegenContext] instead.
*/
open class CoreCodegenContext(
/**
* The smithy model.
*
* Note: This model may or not be pruned to the given service closure, so ensure that `serviceShape` is used as
* an entry point.
*/
open val model: Model,
/**
* The "canonical" symbol provider to convert Smithy [Shape]s into [Symbol]s, which have an associated [RustType].
*/
open val symbolProvider: RustSymbolProvider,
/**
* Entrypoint service shape for code generation.
*/
open val serviceShape: ServiceShape,
/**
* Shape indicating the protocol to generate, e.g. RestJson1.
*/
open val protocol: ShapeId,
/**
* Settings loaded from `smithy-build.json`.
*/
open val settings: CoreRustSettings,
/**
* Are we generating code for a smithy-rs client or server?
*
* Several code generators are reused by both the client and server plugins, but only deviate in small and contained
* parts (e.g. changing a return type or adding an attribute).
* Instead of splitting the generator in two or setting up an inheritance relationship, sometimes it's best
* to just lookup this flag.
*/
open val target: CodegenTarget,
) {
/**
* Configuration of the runtime package:
* - Where are the runtime crates (smithy-*) located on the file system? Or are they versioned?
* - What are they called?
*/
// This is just a convenience. To avoid typing `context.settings.runtimeConfig`, you can simply write
// `context.runtimeConfig`.
val runtimeConfig: RuntimeConfig by lazy { settings.runtimeConfig }
/**
* The name of the cargo crate to generate e.g. `aws-sdk-s3`
* This is loaded from the smithy-build.json during codegen.
*/
// This is just a convenience. To avoid typing `context.settings.moduleName`, you can simply write
// `context.moduleName`.
val moduleName: String by lazy { settings.moduleName }
/**
* A moduleName for a crate uses kebab-case. When you want to `use` a crate in Rust code,
* it must be in snake-case. Call this method to get this crate's name in snake-case.
*/
fun moduleUseName() = moduleName.replace("-", "_")
}

View File

@ -17,73 +17,83 @@ import java.util.Optional
import java.util.logging.Logger
import kotlin.streams.toList
private const val SERVICE = "service"
private const val MODULE_NAME = "module"
private const val MODULE_DESCRIPTION = "moduleDescription"
private const val MODULE_VERSION = "moduleVersion"
private const val MODULE_AUTHORS = "moduleAuthors"
private const val MODULE_REPOSITORY = "moduleRepository"
private const val RUNTIME_CONFIG = "runtimeConfig"
private const val LICENSE = "license"
private const val EXAMPLES = "examples"
private const val CUSTOMIZATION_CONFIG = "customizationConfig"
const val SERVICE = "service"
const val MODULE_NAME = "module"
const val MODULE_DESCRIPTION = "moduleDescription"
const val MODULE_VERSION = "moduleVersion"
const val MODULE_AUTHORS = "moduleAuthors"
const val MODULE_REPOSITORY = "moduleRepository"
const val RUNTIME_CONFIG = "runtimeConfig"
const val LICENSE = "license"
const val EXAMPLES = "examples"
const val CUSTOMIZATION_CONFIG = "customizationConfig"
const val CODEGEN_SETTINGS = "codegen"
/**
* Configuration of codegen settings
* [CoreCodegenConfig] contains code-generation configuration that is _common to all_ smithy-rs plugins.
*
* [renameExceptions]: Rename `Exception` to `Error` in the generated SDK
* [includeFluentClient]: Generate a `client` module in the generated SDK (currently the AWS SDK sets this to false
* and generates its own client)
* If your configuration is specific to the `rust-codegen` client plugin, put it in [ClientCodegenContext] instead.
* If your configuration is specific to the `rust-server-codegen` server plugin, put it in [ServerCodegenContext] instead.
*
* [addMessageToErrors]: Adds a `message` field automatically to all error shapes
* [formatTimeoutSeconds]: Timeout for running cargo fmt at the end of code generation
* [debugMode]: Generate comments in the generated code indicating where code was generated from
*/
data class CodegenConfig(
val renameExceptions: Boolean = true,
val includeFluentClient: Boolean = true,
val addMessageToErrors: Boolean = true,
val formatTimeoutSeconds: Int = 20,
/** Generate comments in the generated code indicating where code was generated from */
val debugMode: Boolean = false,
open class CoreCodegenConfig(
open val formatTimeoutSeconds: Int = defaultFormatTimeoutSeconds,
open val debugMode: Boolean = defaultDebugMode,
// TODO(EventStream): [CLEANUP] Remove this property when turning on Event Stream for all services
val eventStreamAllowList: Set<String> = emptySet(),
open val eventStreamAllowList: Set<String> = defaultEventStreamAllowList,
) {
companion object {
fun fromNode(node: Optional<ObjectNode>): CodegenConfig {
return if (node.isPresent) {
CodegenConfig(
node.get().getBooleanMemberOrDefault("renameErrors", true),
node.get().getBooleanMemberOrDefault("includeFluentClient", true),
node.get().getBooleanMemberOrDefault("addMessageToErrors", true),
node.get().getNumberMemberOrDefault("formatTimeoutSeconds", 20).toInt(),
node.get().getBooleanMemberOrDefault("debugMode", false),
const val defaultFormatTimeoutSeconds = 20
const val defaultDebugMode = false
val defaultEventStreamAllowList: Set<String> = emptySet()
fun fromNode(node: Optional<ObjectNode>): CoreCodegenConfig =
if (node.isPresent) {
CoreCodegenConfig(
node.get().getNumberMemberOrDefault("formatTimeoutSeconds", defaultFormatTimeoutSeconds).toInt(),
node.get().getBooleanMemberOrDefault("debugMode", defaultDebugMode),
node.get().getArrayMember("eventStreamAllowList")
.map { array -> array.toList().mapNotNull { node -> node.asStringNode().orNull()?.value } }
.orNull()?.toSet() ?: emptySet()
.orNull()?.toSet() ?: defaultEventStreamAllowList,
)
} else {
CodegenConfig()
CoreCodegenConfig(
formatTimeoutSeconds = defaultFormatTimeoutSeconds,
debugMode = defaultDebugMode,
eventStreamAllowList = defaultEventStreamAllowList
)
}
}
}
}
/**
* Settings used by [RustCodegenPlugin]
* [CoreRustSettings] contains crate settings that are _common to all_ smithy-rs plugins.
*
* If your setting is specific to the crate that the `rust-codegen` client plugin generates, put it in
* [ClientCodegenContext] instead.
* If your setting is specific to the crate that the `rust-server-codegen` server plugin generates, put it in
* [ServerCodegenContext] instead.
*/
class RustSettings(
val service: ShapeId,
val moduleName: String,
val moduleVersion: String,
val moduleAuthors: List<String>,
val moduleDescription: String?,
val moduleRepository: String?,
val runtimeConfig: RuntimeConfig,
val codegenConfig: CodegenConfig,
val license: String?,
val examplesUri: String? = null,
val customizationConfig: ObjectNode? = null
open class CoreRustSettings(
open val service: ShapeId,
open val moduleName: String,
open val moduleVersion: String,
open val moduleAuthors: List<String>,
open val moduleDescription: String?,
open val moduleRepository: String?,
/**
* Configuration of the runtime package:
* - Where are the runtime crates (smithy-*) located on the file system? Or are they versioned?
* - What are they called?
*/
open val runtimeConfig: RuntimeConfig,
open val codegenConfig: CoreCodegenConfig,
open val license: String?,
open val examplesUri: String? = null,
open val customizationConfig: ObjectNode? = null
) {
/**
@ -100,70 +110,11 @@ class RustSettings(
}
companion object {
private val LOGGER: Logger = Logger.getLogger(RustSettings::class.java.name)
private val LOGGER: Logger = Logger.getLogger(CoreRustSettings::class.java.name)
/**
* Create settings from a configuration object node.
*
* @param model Model to infer the service from (if not explicitly set in config)
* @param config Config object to load
* @throws software.amazon.smithy.model.node.ExpectationNotMetException
* @return Returns the extracted settings
*/
fun from(model: Model, config: ObjectNode): RustSettings {
val codegenSettings = config.getObjectMember(CODEGEN_SETTINGS)
val codegenConfig = CodegenConfig.fromNode(codegenSettings)
return fromCodegenConfig(model, config, codegenConfig)
}
/**
* Create settings from a configuration object node and CodegenConfig.
*
* @param model Model to infer the service from (if not explicitly set in config)
* @param config Config object to load
* @param codegenConfig CodegenConfig object to use
* @throws software.amazon.smithy.model.node.ExpectationNotMetException
* @return Returns the extracted settings
*/
fun fromCodegenConfig(model: Model, config: ObjectNode, codegenConfig: CodegenConfig): RustSettings {
config.warnIfAdditionalProperties(
arrayListOf(
SERVICE,
MODULE_NAME,
MODULE_DESCRIPTION,
MODULE_AUTHORS,
MODULE_VERSION,
MODULE_REPOSITORY,
RUNTIME_CONFIG,
CODEGEN_SETTINGS,
EXAMPLES,
LICENSE,
CUSTOMIZATION_CONFIG
)
)
val service = config.getStringMember(SERVICE)
.map(StringNode::expectShapeId)
.orElseGet { inferService(model) }
val runtimeConfig = config.getObjectMember(RUNTIME_CONFIG)
return RustSettings(
service = service,
moduleName = config.expectStringMember(MODULE_NAME).value,
moduleVersion = config.expectStringMember(MODULE_VERSION).value,
moduleAuthors = config.expectArrayMember(MODULE_AUTHORS).map { it.expectStringNode().value },
moduleDescription = config.getStringMember(MODULE_DESCRIPTION).orNull()?.value,
moduleRepository = config.getStringMember(MODULE_REPOSITORY).orNull()?.value,
runtimeConfig = RuntimeConfig.fromNode(runtimeConfig),
codegenConfig,
license = config.getStringMember(LICENSE).orNull()?.value,
examplesUri = config.getStringMember(EXAMPLES).orNull()?.value,
customizationConfig = config.getObjectMember(CUSTOMIZATION_CONFIG).orNull()
)
}
// infer the service to generate from a model
private fun inferService(model: Model): ShapeId {
// Infer the service to generate from a model.
@JvmStatic
protected fun inferService(model: Model): ShapeId {
val services = model.shapes(ServiceShape::class.java)
.map(Shape::getId)
.sorted()
@ -189,5 +140,63 @@ class RustSettings(
}
}
}
/**
* Create settings from a configuration object node.
*
* @param model Model to infer the service from (if not explicitly set in config)
* @param config Config object to load
* @return Returns the extracted settings
*/
fun from(model: Model, config: ObjectNode): CoreRustSettings {
val codegenSettings = config.getObjectMember(CODEGEN_SETTINGS)
val coreCodegenConfig = CoreCodegenConfig.fromNode(codegenSettings)
return fromCodegenConfig(model, config, coreCodegenConfig)
}
/**
* Create settings from a configuration object node and CodegenConfig.
*
* @param model Model to infer the service from (if not explicitly set in config)
* @param config Config object to load
* @param coreCodegenConfig CodegenConfig object to use
* @return Returns the extracted settings
*/
private fun fromCodegenConfig(model: Model, config: ObjectNode, coreCodegenConfig: CoreCodegenConfig): CoreRustSettings {
config.warnIfAdditionalProperties(
arrayListOf(
SERVICE,
MODULE_NAME,
MODULE_DESCRIPTION,
MODULE_AUTHORS,
MODULE_VERSION,
MODULE_REPOSITORY,
RUNTIME_CONFIG,
CODEGEN_SETTINGS,
EXAMPLES,
LICENSE,
CUSTOMIZATION_CONFIG
)
)
val service = config.getStringMember(SERVICE)
.map(StringNode::expectShapeId)
.orElseGet { inferService(model) }
val runtimeConfig = config.getObjectMember(RUNTIME_CONFIG)
return CoreRustSettings(
service,
moduleName = config.expectStringMember(MODULE_NAME).value,
moduleVersion = config.expectStringMember(MODULE_VERSION).value,
moduleAuthors = config.expectArrayMember(MODULE_AUTHORS).map { it.expectStringNode().value },
moduleDescription = config.getStringMember(MODULE_DESCRIPTION).orNull()?.value,
moduleRepository = config.getStringMember(MODULE_REPOSITORY).orNull()?.value,
runtimeConfig = RuntimeConfig.fromNode(runtimeConfig),
codegenConfig = coreCodegenConfig,
license = config.getStringMember(LICENSE).orNull()?.value,
examplesUri = config.getStringMember(EXAMPLES).orNull()?.value,
customizationConfig = config.getObjectMember(CUSTOMIZATION_CONFIG).orNull()
)
}
}
}

View File

@ -14,13 +14,17 @@ import software.amazon.smithy.rust.codegen.rustlang.Attribute.Companion.NonExhau
import software.amazon.smithy.rust.codegen.rustlang.RustReservedWordSymbolProvider
import software.amazon.smithy.rust.codegen.smithy.customizations.ClientCustomizations
import software.amazon.smithy.rust.codegen.smithy.customize.CombinedCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.customize.RequiredCustomizations
import software.amazon.smithy.rust.codegen.smithy.generators.client.FluentClientDecorator
import java.util.logging.Level
import java.util.logging.Logger
/** Rust Codegen Plugin
* This is the entrypoint for code generation, triggered by the smithy-build plugin.
* `resources/META-INF.services/software.amazon.smithy.build.SmithyBuildPlugin` refers to this class by name which
* enables the smithy-build plugin to invoke `execute` with all of the Smithy plugin context + models.
/**
* Rust Codegen Plugin
*
* This is the entrypoint for code generation, triggered by the smithy-build plugin.
* `resources/META-INF.services/software.amazon.smithy.build.SmithyBuildPlugin` refers to this class by name which
* enables the smithy-build plugin to invoke `execute` with all of the Smithy plugin context + models.
*/
class RustCodegenPlugin : SmithyBuildPlugin {
override fun getName(): String = "rust-codegen"
@ -28,12 +32,18 @@ class RustCodegenPlugin : SmithyBuildPlugin {
override fun execute(context: PluginContext) {
// Suppress extremely noisy logs about reserved words
Logger.getLogger(ReservedWordSymbolProvider::class.java.name).level = Level.OFF
// Discover `RustCodegenDecorators` on the classpath. `RustCodegenDecorator` return different types of
// customization. A customization is a function of:
// Discover `RustCodegenDecorators` on the classpath. `RustCodegenDecorator` returns different types of
// customizations. A customization is a function of:
// - location (e.g. the mutate section of an operation)
// - context (e.g. the of the operation)
// - writer: The active RustWriter at the given location
val codegenDecorator = CombinedCodegenDecorator.fromClasspath(context, ClientCustomizations())
val codegenDecorator =
CombinedCodegenDecorator.fromClasspath(
context,
ClientCustomizations(),
RequiredCustomizations(),
FluentClientDecorator()
)
// CodegenVisitor is the main driver of code generation that traverses the model and generates code
CodegenVisitor(context, codegenDecorator).execute()
@ -46,7 +56,7 @@ class RustCodegenPlugin : SmithyBuildPlugin {
* The Symbol provider is composed of a base `SymbolVisitor` which handles the core functionality, then is layered
* with other symbol providers, documented inline, to handle the full scope of Smithy types.
*/
fun baseSymbolProvider(model: Model, serviceShape: ServiceShape, symbolVisitorConfig: SymbolVisitorConfig = DefaultConfig) =
fun baseSymbolProvider(model: Model, serviceShape: ServiceShape, symbolVisitorConfig: SymbolVisitorConfig) =
SymbolVisitor(model, serviceShape = serviceShape, config = symbolVisitorConfig)
// Generate different types for EventStream shapes (e.g. transcribe streaming)
.let { EventStreamSymbolProvider(symbolVisitorConfig.runtimeConfig, it, model) }

View File

@ -0,0 +1,30 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package software.amazon.smithy.rust.codegen.smithy
import software.amazon.smithy.model.Model
import software.amazon.smithy.model.shapes.ServiceShape
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.rust.codegen.smithy.generators.CodegenTarget
/**
* [ServerCodegenContext] contains code-generation context that is _specific_ to the [RustCodegenServerPlugin] plugin
* from the `rust-codegen-server` subproject.
*
* It inherits from [CoreCodegenContext], which contains code-generation context that is common to _all_ smithy-rs plugins.
*
* This class has to live in the `codegen` subproject because it is referenced in common generators to both client
* and server (like [JsonParserGenerator]).
*/
data class ServerCodegenContext(
override val model: Model,
override val symbolProvider: RustSymbolProvider,
override val serviceShape: ServiceShape,
override val protocol: ShapeId,
override val settings: ServerRustSettings,
) : CoreCodegenContext(
model, symbolProvider, serviceShape, protocol, settings, CodegenTarget.SERVER
)

View File

@ -0,0 +1,91 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package software.amazon.smithy.rust.codegen.smithy
import software.amazon.smithy.model.Model
import software.amazon.smithy.model.node.ObjectNode
import software.amazon.smithy.model.shapes.ShapeId
import java.util.Optional
/**
* [ServerRustSettings] and [ServerCodegenConfig] classes.
*
* These classes are entirely analogous to [ClientRustSettings] and [ClientCodegenConfig]. Refer to the documentation
* for those.
*
* These classes have to live in the `codegen` subproject because they are referenced in [ServerCodegenContext],
* which is used in common generators to both client and server.
*/
/**
* Settings used by [RustCodegenServerPlugin].
*/
data class ServerRustSettings(
override val service: ShapeId,
override val moduleName: String,
override val moduleVersion: String,
override val moduleAuthors: List<String>,
override val moduleDescription: String?,
override val moduleRepository: String?,
override val runtimeConfig: RuntimeConfig,
override val codegenConfig: ServerCodegenConfig,
override val license: String?,
override val examplesUri: String?,
override val customizationConfig: ObjectNode?
) : CoreRustSettings(
service,
moduleName,
moduleVersion,
moduleAuthors,
moduleDescription,
moduleRepository,
runtimeConfig,
codegenConfig,
license,
examplesUri,
customizationConfig
) {
companion object {
fun from(model: Model, config: ObjectNode): ServerRustSettings {
val coreRustSettings = CoreRustSettings.from(model, config)
val codegenSettingsNode = config.getObjectMember(CODEGEN_SETTINGS)
val coreCodegenConfig = CoreCodegenConfig.fromNode(codegenSettingsNode)
return ServerRustSettings(
service = coreRustSettings.service,
moduleName = coreRustSettings.moduleName,
moduleVersion = coreRustSettings.moduleVersion,
moduleAuthors = coreRustSettings.moduleAuthors,
moduleDescription = coreRustSettings.moduleDescription,
moduleRepository = coreRustSettings.moduleRepository,
runtimeConfig = coreRustSettings.runtimeConfig,
codegenConfig = ServerCodegenConfig.fromCodegenConfigAndNode(coreCodegenConfig, codegenSettingsNode),
license = coreRustSettings.license,
examplesUri = coreRustSettings.examplesUri,
customizationConfig = coreRustSettings.customizationConfig
)
}
}
}
data class ServerCodegenConfig(
override val formatTimeoutSeconds: Int,
override val debugMode: Boolean,
override val eventStreamAllowList: Set<String>,
) : CoreCodegenConfig(
formatTimeoutSeconds, debugMode, eventStreamAllowList
) {
companion object {
// Note `node` is unused, because at the moment `ServerCodegenConfig` has the same properties as
// `CodegenConfig`. In the future, the server will have server-specific codegen options just like the client
// does.
fun fromCodegenConfigAndNode(coreCodegenConfig: CoreCodegenConfig, node: Optional<ObjectNode>) =
ServerCodegenConfig(
formatTimeoutSeconds = coreCodegenConfig.formatTimeoutSeconds,
debugMode = coreCodegenConfig.debugMode,
eventStreamAllowList = coreCodegenConfig.eventStreamAllowList,
)
}
}

View File

@ -62,19 +62,11 @@ val SimpleShapes: Map<KClass<out Shape>, RustType> = mapOf(
data class SymbolVisitorConfig(
val runtimeConfig: RuntimeConfig,
val codegenConfig: CodegenConfig,
val handleRustBoxing: Boolean = true,
val handleRequired: Boolean = false
val renameExceptions: Boolean,
val handleRustBoxing: Boolean,
val handleRequired: Boolean,
)
val DefaultConfig =
SymbolVisitorConfig(
runtimeConfig = RuntimeConfig(),
handleRustBoxing = true,
handleRequired = false,
codegenConfig = CodegenConfig()
)
/**
* Container type for the file a symbol should be written to
*
@ -166,7 +158,7 @@ fun SymbolProvider.toOptional(member: MemberShape, value: String): String = valu
class SymbolVisitor(
private val model: Model,
private val serviceShape: ServiceShape?,
private val config: SymbolVisitorConfig = DefaultConfig
private val config: SymbolVisitorConfig
) : RustSymbolProvider,
ShapeVisitor<Symbol> {
private val nullableIndex = NullableIndex.of(model)
@ -313,7 +305,7 @@ class SymbolVisitor(
val isError = shape.hasTrait<ErrorTrait>()
val isInput = shape.hasTrait<SyntheticInputTrait>()
val isOutput = shape.hasTrait<SyntheticOutputTrait>()
val name = shape.contextName().toPascalCase().letIf(isError && config.codegenConfig.renameExceptions) {
val name = shape.contextName().toPascalCase().letIf(isError && config.renameExceptions) {
it.replace("Exception", "Error")
}
val builder = symbolBuilder(shape, RustType.Opaque(name))

View File

@ -42,7 +42,11 @@ val AllowDocsLints = listOf(
"bare_urls"
)
class AllowLintsGenerator(private val bareLints: List<String> = listOf(), private val clippyLints: List<String> = ClippyAllowLints, private val docsLints: List<String> = AllowDocsLints) : LibRsCustomization() {
class AllowLintsGenerator(
private val bareLints: List<String> = listOf(),
private val clippyLints: List<String> = ClippyAllowLints,
private val docsLints: List<String> = AllowDocsLints
) : LibRsCustomization() {
override fun section(section: LibRsSection) = when (section) {
is LibRsSection.Attributes -> writable {
bareLints.forEach {

View File

@ -5,21 +5,19 @@
package software.amazon.smithy.rust.codegen.smithy.customizations
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.generators.LibRsCustomization
/**
* Customizations that apply only to generated clients
* Customizations that apply only to generated clients.
*/
class ClientCustomizations : RustCodegenDecorator {
class ClientCustomizations : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "ClientCustomizations"
override val order: Byte = 0
override fun libRsCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<LibRsCustomization>
): List<LibRsCustomization> {
return baseCustomizations + ClientDocsGenerator()
}
): List<LibRsCustomization> = baseCustomizations + ClientDocsGenerator()
}

View File

@ -20,11 +20,10 @@ class ClientDocsGenerator : LibRsCustomization() {
else -> emptySection
}
}
}
private fun crateLayout(): Writable = writable {
containerDocs(
"""
private fun crateLayout(): Writable = writable {
containerDocs(
"""
The entry point for most customers will be [`Client`]. [`Client`] exposes one method for each API offered
by the service.
@ -35,5 +34,6 @@ private fun crateLayout(): Writable = writable {
The other modules within this crate are not required for normal usage.
""".trimEnd()
)
)
}
}

View File

@ -5,7 +5,7 @@
package software.amazon.smithy.rust.codegen.smithy.customizations
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.generators.ManifestCustomizations
@ -48,11 +48,12 @@ fun DocsRsMetadataSettings.asMap(): Map<String, Any> {
* # Notes
* This decorator is not used by default, code generators must manually configure and include it in their builds.
*/
class DocsRsMetadataDecorator(private val docsRsMetadataSettings: DocsRsMetadataSettings) : RustCodegenDecorator {
class DocsRsMetadataDecorator(private val docsRsMetadataSettings: DocsRsMetadataSettings) :
RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "docsrs-metadata"
override val order: Byte = 0
override fun crateManifestCustomizations(codegenContext: CodegenContext): ManifestCustomizations {
override fun crateManifestCustomizations(codegenContext: ClientCodegenContext): ManifestCustomizations {
return docsRsMetadataSettings.asMap()
}
}

View File

@ -11,20 +11,20 @@ import software.amazon.smithy.rust.codegen.rustlang.Writable
import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.withBlock
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.customize.OperationCustomization
import software.amazon.smithy.rust.codegen.smithy.customize.OperationSection
import software.amazon.smithy.rust.codegen.smithy.generators.EndpointTraitBindings
class EndpointPrefixGenerator(private val codegenContext: CodegenContext, private val shape: OperationShape) :
class EndpointPrefixGenerator(private val coreCodegenContext: CoreCodegenContext, private val shape: OperationShape) :
OperationCustomization() {
override fun section(section: OperationSection): Writable = when (section) {
is OperationSection.MutateRequest -> writable {
shape.getTrait(EndpointTrait::class.java).map { epTrait ->
val endpointTraitBindings = EndpointTraitBindings(
codegenContext.model,
codegenContext.symbolProvider,
codegenContext.runtimeConfig,
coreCodegenContext.model,
coreCodegenContext.symbolProvider,
coreCodegenContext.runtimeConfig,
shape,
epTrait
)

View File

@ -13,7 +13,7 @@ import software.amazon.smithy.rust.codegen.rustlang.Writable
import software.amazon.smithy.rust.codegen.rustlang.asType
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.customize.OperationCustomization
import software.amazon.smithy.rust.codegen.smithy.customize.OperationSection
@ -23,14 +23,14 @@ import software.amazon.smithy.rust.codegen.util.hasTrait
import software.amazon.smithy.rust.codegen.util.inputShape
class HttpChecksumRequiredGenerator(
private val codegenContext: CodegenContext,
private val coreCodegenContext: CoreCodegenContext,
private val operationShape: OperationShape
) : OperationCustomization() {
override fun section(section: OperationSection): Writable {
if (!operationShape.hasTrait<HttpChecksumRequiredTrait>()) {
return emptySection
}
if (operationShape.inputShape(codegenContext.model).hasStreamingMember(codegenContext.model)) {
if (operationShape.inputShape(coreCodegenContext.model).hasStreamingMember(coreCodegenContext.model)) {
throw CodegenException("HttpChecksum required cannot be applied to a streaming shape")
}
return when (section) {
@ -52,8 +52,8 @@ class HttpChecksumRequiredGenerator(
""",
"md5" to CargoDependency.Md5.asType(),
"http" to CargoDependency.Http.asType(),
"base64_encode" to RuntimeType.Base64Encode(codegenContext.runtimeConfig),
"BuildError" to codegenContext.runtimeConfig.operationBuildError()
"base64_encode" to RuntimeType.Base64Encode(coreCodegenContext.runtimeConfig),
"BuildError" to coreCodegenContext.runtimeConfig.operationBuildError()
)
}
else -> emptySection

View File

@ -10,7 +10,7 @@ import software.amazon.smithy.model.shapes.OperationShape
import software.amazon.smithy.rust.codegen.rustlang.Writable
import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.customize.OperationCustomization
@ -24,19 +24,19 @@ private fun RuntimeConfig.defaultHttpVersionList(): RuntimeType =
this.httpVersionModule().member("DEFAULT_HTTP_VERSION_LIST")
class HttpVersionListCustomization(
private val codegenContext: CodegenContext,
private val coreCodegenContext: CoreCodegenContext,
private val operationShape: OperationShape
) : OperationCustomization() {
private val defaultHttpVersions = codegenContext.runtimeConfig.defaultHttpVersionList().fullyQualifiedName()
private val defaultHttpVersions = coreCodegenContext.runtimeConfig.defaultHttpVersionList().fullyQualifiedName()
override fun section(section: OperationSection): Writable {
val awsProtocolTrait = codegenContext.serviceShape.getTrait<AwsProtocolTrait>()
val awsProtocolTrait = coreCodegenContext.serviceShape.getTrait<AwsProtocolTrait>()
val supportedHttpProtocolVersions = if (awsProtocolTrait == null) {
// No protocol trait was defined, use default http versions
"$defaultHttpVersions.clone()"
} else {
// Figure out whether we're dealing with an EventStream operation and fetch the corresponding list of desired HTTP versions
val versionList = if (operationShape.isEventStream(codegenContext.model)) awsProtocolTrait.eventStreamHttp else awsProtocolTrait.http
val versionList = if (operationShape.isEventStream(coreCodegenContext.model)) awsProtocolTrait.eventStreamHttp else awsProtocolTrait.http
if (versionList.isEmpty()) {
// If no desired versions are specified, go with the default
"$defaultHttpVersions.clone()"

View File

@ -10,16 +10,16 @@ import software.amazon.smithy.model.traits.IdempotencyTokenTrait
import software.amazon.smithy.rust.codegen.rustlang.Writable
import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.customize.OperationCustomization
import software.amazon.smithy.rust.codegen.smithy.customize.OperationSection
import software.amazon.smithy.rust.codegen.util.findMemberWithTrait
import software.amazon.smithy.rust.codegen.util.inputShape
class IdempotencyTokenGenerator(codegenContext: CodegenContext, private val operationShape: OperationShape) :
class IdempotencyTokenGenerator(coreCodegenContext: CoreCodegenContext, private val operationShape: OperationShape) :
OperationCustomization() {
private val model = codegenContext.model
private val symbolProvider = codegenContext.symbolProvider
private val model = coreCodegenContext.model
private val symbolProvider = coreCodegenContext.symbolProvider
private val idempotencyTokenMember = operationShape.inputShape(model).findMemberWithTrait<IdempotencyTokenTrait>(model)
override fun section(section: OperationSection): Writable {
if (idempotencyTokenMember == null) {

View File

@ -9,7 +9,8 @@ import software.amazon.smithy.rust.codegen.rustlang.Writable
import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
@ -66,28 +67,28 @@ fn test_1() {
}
*/
class RetryConfigDecorator : RustCodegenDecorator {
class RetryConfigDecorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "RetryConfig"
override val order: Byte = 0
override fun configCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<ConfigCustomization>
): List<ConfigCustomization> {
return baseCustomizations + RetryConfigProviderConfig(codegenContext)
}
override fun libRsCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<LibRsCustomization>
): List<LibRsCustomization> {
return baseCustomizations + PubUseRetryConfig(codegenContext.runtimeConfig)
}
}
class RetryConfigProviderConfig(codegenContext: CodegenContext) : ConfigCustomization() {
private val retryConfig = smithyTypesRetry(codegenContext.runtimeConfig)
private val moduleUseName = codegenContext.moduleUseName()
class RetryConfigProviderConfig(coreCodegenContext: CoreCodegenContext) : ConfigCustomization() {
private val retryConfig = smithyTypesRetry(coreCodegenContext.runtimeConfig)
private val moduleUseName = coreCodegenContext.moduleUseName()
private val codegenScope = arrayOf("RetryConfig" to retryConfig.member("RetryConfig"))
override fun section(section: ServiceConfig) = writable {
when (section) {

View File

@ -7,7 +7,8 @@ package software.amazon.smithy.rust.codegen.smithy.customizations
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
@ -115,21 +116,21 @@ impl Builder {
}
*/
class SleepImplDecorator : RustCodegenDecorator {
class SleepImplDecorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "AsyncSleep"
override val order: Byte = 0
override fun configCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<ConfigCustomization>
): List<ConfigCustomization> {
return baseCustomizations + SleepImplProviderConfig(codegenContext)
}
}
class SleepImplProviderConfig(codegenContext: CodegenContext) : ConfigCustomization() {
private val sleepModule = smithyAsyncRtSleep(codegenContext.runtimeConfig)
private val moduleUseName = codegenContext.moduleUseName()
class SleepImplProviderConfig(coreCodegenContext: CoreCodegenContext) : ConfigCustomization() {
private val sleepModule = smithyAsyncRtSleep(coreCodegenContext.runtimeConfig)
private val moduleUseName = coreCodegenContext.moduleUseName()
private val codegenScope = arrayOf(
"AsyncSleep" to sleepModule.member("AsyncSleep"),
"Sleep" to sleepModule.member("Sleep"),

View File

@ -7,7 +7,8 @@ package software.amazon.smithy.rust.codegen.smithy.customizations
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.generators.config.ConfigCustomization
@ -102,22 +103,22 @@ fn test_1() {
}
*/
class TimeoutConfigDecorator : RustCodegenDecorator {
class TimeoutConfigDecorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "TimeoutConfig"
override val order: Byte = 0
override fun configCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<ConfigCustomization>
): List<ConfigCustomization> {
return baseCustomizations + TimeoutConfigProviderConfig(codegenContext)
}
}
class TimeoutConfigProviderConfig(codegenContext: CodegenContext) : ConfigCustomization() {
private val smithyTypesCrate = codegenContext.runtimeConfig.runtimeCrate("types")
class TimeoutConfigProviderConfig(coreCodegenContext: CoreCodegenContext) : ConfigCustomization() {
private val smithyTypesCrate = coreCodegenContext.runtimeConfig.runtimeCrate("types")
private val timeoutModule = RuntimeType("timeout", smithyTypesCrate, "aws_smithy_types")
private val moduleUseName = codegenContext.moduleUseName()
private val moduleUseName = coreCodegenContext.moduleUseName()
private val codegenScope = arrayOf(
"TimeoutConfig" to timeoutModule.member("Config"),
)

View File

@ -7,7 +7,7 @@ package software.amazon.smithy.rust.codegen.smithy.customize
import software.amazon.smithy.model.shapes.OperationShape
import software.amazon.smithy.rust.codegen.rustlang.Feature
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RustCrate
import software.amazon.smithy.rust.codegen.smithy.customizations.AllowLintsGenerator
import software.amazon.smithy.rust.codegen.smithy.customizations.CrateVersionGenerator
@ -18,34 +18,33 @@ import software.amazon.smithy.rust.codegen.smithy.customizations.IdempotencyToke
import software.amazon.smithy.rust.codegen.smithy.customizations.SmithyTypesPubUseGenerator
import software.amazon.smithy.rust.codegen.smithy.generators.LibRsCustomization
/** A set of customizations that are included in all protocols.
/**
* A set of customizations that are included in all protocols.
*
* This exists as a convenient place to gather these modifications, these are not true customizations.
*/
class RequiredCustomizations : RustCodegenDecorator {
class RequiredCustomizations : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "Required"
override val order: Byte = -1
override fun operationCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
operation: OperationShape,
baseCustomizations: List<OperationCustomization>
): List<OperationCustomization> {
return baseCustomizations +
): List<OperationCustomization> =
baseCustomizations +
IdempotencyTokenGenerator(codegenContext, operation) +
EndpointPrefixGenerator(codegenContext, operation) +
HttpChecksumRequiredGenerator(codegenContext, operation) +
HttpVersionListCustomization(codegenContext, operation)
}
override fun libRsCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<LibRsCustomization>
): List<LibRsCustomization> {
return baseCustomizations + CrateVersionGenerator() + SmithyTypesPubUseGenerator(codegenContext.runtimeConfig) + AllowLintsGenerator()
}
): List<LibRsCustomization> =
baseCustomizations + CrateVersionGenerator() + SmithyTypesPubUseGenerator(codegenContext.runtimeConfig) + AllowLintsGenerator()
override fun extras(codegenContext: CodegenContext, rustCrate: RustCrate) {
override fun extras(codegenContext: ClientCodegenContext, rustCrate: RustCrate) {
// Add rt-tokio feature for `ByteStream::from_path`
rustCrate.mergeFeature(Feature("rt-tokio", true, listOf("aws-smithy-http/rt-tokio")))
}

View File

@ -10,16 +10,15 @@ import software.amazon.smithy.model.Model
import software.amazon.smithy.model.shapes.OperationShape
import software.amazon.smithy.model.shapes.ServiceShape
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RustCrate
import software.amazon.smithy.rust.codegen.smithy.RustSymbolProvider
import software.amazon.smithy.rust.codegen.smithy.generators.LibRsCustomization
import software.amazon.smithy.rust.codegen.smithy.generators.ManifestCustomizations
import software.amazon.smithy.rust.codegen.smithy.generators.client.FluentClientDecorator
import software.amazon.smithy.rust.codegen.smithy.generators.config.ConfigCustomization
import software.amazon.smithy.rust.codegen.smithy.protocols.ProtocolMap
import software.amazon.smithy.rust.codegen.util.deepMergeWith
import java.util.ServiceLoader
import java.util.*
import java.util.logging.Logger
/**
@ -29,7 +28,7 @@ import java.util.logging.Logger
* AWS services. A different downstream customer may wish to add a different set of derive
* attributes to the generated classes.
*/
interface RustCodegenDecorator {
interface RustCodegenDecorator<C : CoreCodegenContext> {
/**
* The name of this [RustCodegenDecorator], used for logging and debug information
*/
@ -41,18 +40,19 @@ interface RustCodegenDecorator {
val order: Byte
fun configCustomizations(
codegenContext: CodegenContext,
codegenContext: C,
baseCustomizations: List<ConfigCustomization>
): List<ConfigCustomization> = baseCustomizations
// This is only used by decorators for smithy-rs _clients_.
fun operationCustomizations(
codegenContext: CodegenContext,
codegenContext: C,
operation: OperationShape,
baseCustomizations: List<OperationCustomization>
): List<OperationCustomization> = baseCustomizations
fun libRsCustomizations(
codegenContext: CodegenContext,
codegenContext: C,
baseCustomizations: List<LibRsCustomization>
): List<LibRsCustomization> = baseCustomizations
@ -61,11 +61,12 @@ interface RustCodegenDecorator {
* added to the Cargo.toml `[package]` section, a `mapOf("package" to mapOf("homepage", "https://example.com"))`
* could be returned. Properties here overwrite the default properties.
*/
fun crateManifestCustomizations(codegenContext: CodegenContext): ManifestCustomizations = emptyMap()
fun crateManifestCustomizations(codegenContext: C): ManifestCustomizations = emptyMap()
fun extras(codegenContext: CodegenContext, rustCrate: RustCrate) {}
fun extras(codegenContext: C, rustCrate: RustCrate) {}
fun protocols(serviceId: ShapeId, currentProtocols: ProtocolMap): ProtocolMap = currentProtocols
fun protocols(serviceId: ShapeId, currentProtocols: ProtocolMap<C>): ProtocolMap<C> =
currentProtocols
fun transformModel(service: ServiceShape, model: Model): Model = model
@ -77,36 +78,36 @@ interface RustCodegenDecorator {
*
* This makes the actual concrete codegen simpler by not needing to deal with multiple separate decorators.
*/
open class CombinedCodegenDecorator(decorators: List<RustCodegenDecorator>) : RustCodegenDecorator {
open class CombinedCodegenDecorator<C : CoreCodegenContext>(decorators: List<RustCodegenDecorator<C>>) : RustCodegenDecorator<C> {
private val orderedDecorators = decorators.sortedBy { it.order }
override val name: String
get() = "MetaDecorator"
override val order: Byte
get() = 0
fun withDecorator(decorator: RustCodegenDecorator) = CombinedCodegenDecorator(orderedDecorators + decorator)
fun withDecorator(decorator: RustCodegenDecorator<C>) = CombinedCodegenDecorator(orderedDecorators + decorator)
override fun configCustomizations(
codegenContext: CodegenContext,
codegenContext: C,
baseCustomizations: List<ConfigCustomization>
): List<ConfigCustomization> {
return orderedDecorators.foldRight(baseCustomizations) { decorator: RustCodegenDecorator, customizations ->
return orderedDecorators.foldRight(baseCustomizations) { decorator: RustCodegenDecorator<C>, customizations ->
decorator.configCustomizations(codegenContext, customizations)
}
}
override fun operationCustomizations(
codegenContext: CodegenContext,
codegenContext: C,
operation: OperationShape,
baseCustomizations: List<OperationCustomization>
): List<OperationCustomization> {
return orderedDecorators.foldRight(baseCustomizations) { decorator: RustCodegenDecorator, customizations ->
return orderedDecorators.foldRight(baseCustomizations) { decorator: RustCodegenDecorator<C>, customizations ->
decorator.operationCustomizations(codegenContext, operation, customizations)
}
}
override fun libRsCustomizations(
codegenContext: CodegenContext,
codegenContext: C,
baseCustomizations: List<LibRsCustomization>
): List<LibRsCustomization> {
return orderedDecorators.foldRight(baseCustomizations) { decorator, customizations ->
@ -117,7 +118,7 @@ open class CombinedCodegenDecorator(decorators: List<RustCodegenDecorator>) : Ru
}
}
override fun protocols(serviceId: ShapeId, currentProtocols: ProtocolMap): ProtocolMap {
override fun protocols(serviceId: ShapeId, currentProtocols: ProtocolMap<C>): ProtocolMap<C> {
return orderedDecorators.foldRight(currentProtocols) { decorator, protocolMap ->
decorator.protocols(serviceId, protocolMap)
}
@ -129,13 +130,13 @@ open class CombinedCodegenDecorator(decorators: List<RustCodegenDecorator>) : Ru
}
}
override fun crateManifestCustomizations(codegenContext: CodegenContext): ManifestCustomizations {
override fun crateManifestCustomizations(codegenContext: C): ManifestCustomizations {
return orderedDecorators.foldRight(emptyMap()) { decorator, customizations ->
customizations.deepMergeWith(decorator.crateManifestCustomizations(codegenContext))
}
}
override fun extras(codegenContext: CodegenContext, rustCrate: RustCrate) {
override fun extras(codegenContext: C, rustCrate: RustCrate) {
return orderedDecorators.forEach { it.extras(codegenContext, rustCrate) }
}
@ -146,16 +147,40 @@ open class CombinedCodegenDecorator(decorators: List<RustCodegenDecorator>) : Ru
}
companion object {
private val logger = Logger.getLogger("RustCodegenSPILoader")
fun fromClasspath(context: PluginContext, vararg extras: RustCodegenDecorator): CombinedCodegenDecorator {
inline fun <reified T : CoreCodegenContext> fromClasspath(
context: PluginContext,
vararg extras: RustCodegenDecorator<T>,
logger: Logger = Logger.getLogger("RustCodegenSPILoader")
): CombinedCodegenDecorator<T> {
val decorators = ServiceLoader.load(
RustCodegenDecorator::class.java,
context.pluginClassLoader.orElse(RustCodegenDecorator::class.java.classLoader)
)
// The JVM's `ServiceLoader` is woefully underpowered in that it can not load classes with generic
// parameters with _fixed_ parameters (like what we're trying to do here; we only want `RustCodegenDecorator`
// classes with code-generation context matching the input `T`).
// There are various workarounds: https://stackoverflow.com/questions/5451734/loading-generic-service-implementations-via-java-util-serviceloader
// All involve loading _all_ classes from the classpath (i.e. all `RustCodegenDecorator<*>`), and then
// filtering them. The most elegant way to filter is arguably by checking if we can cast the loaded
// class to what we want.
.filter {
try {
it as RustCodegenDecorator<T>
true
} catch (e: ClassCastException) {
false
}
}
.onEach {
logger.info("Adding Codegen Decorator: ${it.javaClass.name}")
}.toList()
return CombinedCodegenDecorator(decorators + RequiredCustomizations() + FluentClientDecorator() + extras)
}
.map {
// Cast is safe because of the filter above.
@Suppress("UNCHECKED_CAST")
it as RustCodegenDecorator<T>
}
.toList()
return CombinedCodegenDecorator(decorators + extras)
}
}
}

View File

@ -10,7 +10,7 @@ import software.amazon.smithy.rust.codegen.rustlang.CargoDependency
import software.amazon.smithy.rust.codegen.rustlang.DependencyScope
import software.amazon.smithy.rust.codegen.rustlang.Feature
import software.amazon.smithy.rust.codegen.rustlang.RustWriter
import software.amazon.smithy.rust.codegen.smithy.RustSettings
import software.amazon.smithy.rust.codegen.smithy.CoreRustSettings
import software.amazon.smithy.rust.codegen.util.deepMergeWith
/**
@ -42,7 +42,7 @@ typealias ManifestCustomizations = Map<String, Any?>
* Generates the crate manifest Cargo.toml file.
*/
class CargoTomlGenerator(
private val settings: RustSettings,
private val settings: CoreRustSettings,
private val writer: RustWriter,
private val manifestCustomizations: ManifestCustomizations,
private val dependencies: List<CargoDependency>,

View File

@ -13,7 +13,7 @@ import software.amazon.smithy.rust.codegen.rustlang.containerDocs
import software.amazon.smithy.rust.codegen.rustlang.escape
import software.amazon.smithy.rust.codegen.rustlang.isEmpty
import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.smithy.RustSettings
import software.amazon.smithy.rust.codegen.smithy.CoreRustSettings
import software.amazon.smithy.rust.codegen.smithy.customize.NamedSectionGenerator
import software.amazon.smithy.rust.codegen.smithy.customize.Section
import software.amazon.smithy.rust.codegen.util.getTrait
@ -31,7 +31,7 @@ sealed class LibRsSection(name: String) : Section(name) {
typealias LibRsCustomization = NamedSectionGenerator<LibRsSection>
class LibRsGenerator(
private val settings: RustSettings,
private val settings: CoreRustSettings,
private val model: Model,
private val modules: List<RustModule>,
private val customizations: List<LibRsCustomization>,

View File

@ -23,7 +23,7 @@ import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.stripOuter
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.RustSymbolProvider
import software.amazon.smithy.rust.codegen.smithy.generators.client.FluentClientGenerics
@ -52,15 +52,15 @@ class PaginatorGenerator private constructor(
companion object {
fun paginatorType(
codegenContext: CodegenContext,
coreCodegenContext: CoreCodegenContext,
generics: FluentClientGenerics,
operationShape: OperationShape
): RuntimeType? {
return if (operationShape.isPaginated(codegenContext.model)) {
return if (operationShape.isPaginated(coreCodegenContext.model)) {
PaginatorGenerator(
codegenContext.model,
codegenContext.symbolProvider,
codegenContext.serviceShape,
coreCodegenContext.model,
coreCodegenContext.symbolProvider,
coreCodegenContext.serviceShape,
operationShape,
generics
).paginatorType()

View File

@ -8,7 +8,7 @@ package software.amazon.smithy.rust.codegen.smithy.generators
import software.amazon.smithy.model.knowledge.TopDownIndex
import software.amazon.smithy.rust.codegen.rustlang.Attribute
import software.amazon.smithy.rust.codegen.rustlang.RustModule
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RustCrate
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.generators.config.ServiceConfigGenerator
@ -29,44 +29,44 @@ class ServiceGenerator(
private val rustCrate: RustCrate,
private val protocolGenerator: ProtocolGenerator,
private val protocolSupport: ProtocolSupport,
private val config: CodegenContext,
private val decorator: RustCodegenDecorator,
private val clientCodegenContext: ClientCodegenContext,
private val decorator: RustCodegenDecorator<ClientCodegenContext>,
) {
private val index = TopDownIndex.of(config.model)
private val index = TopDownIndex.of(clientCodegenContext.model)
/**
* Render Service-specific code. Code will end up in different files via `useShapeWriter`. See `SymbolVisitor.kt`
* which assigns a symbol location to each shape.
*/
fun render() {
val operations = index.getContainedOperations(config.serviceShape).sortedBy { it.id }
val operations = index.getContainedOperations(clientCodegenContext.serviceShape).sortedBy { it.id }
operations.map { operation ->
rustCrate.useShapeWriter(operation) { operationWriter ->
rustCrate.useShapeWriter(operation.inputShape(config.model)) { inputWriter ->
rustCrate.useShapeWriter(operation.inputShape(clientCodegenContext.model)) { inputWriter ->
// Render the operation shape & serializers input `input.rs`
protocolGenerator.renderOperation(
operationWriter,
inputWriter,
operation,
decorator.operationCustomizations(config, operation, listOf())
decorator.operationCustomizations(clientCodegenContext, operation, listOf())
)
// render protocol tests into `operation.rs` (note operationWriter vs. inputWriter)
ProtocolTestGenerator(config, protocolSupport, operation, operationWriter).render()
ProtocolTestGenerator(clientCodegenContext, protocolSupport, operation, operationWriter).render()
}
}
// Render a service-level error enum containing every error that the service can emit
rustCrate.withModule(RustModule.Error) { writer ->
CombinedErrorGenerator(config.model, config.symbolProvider, operation).render(writer)
CombinedErrorGenerator(clientCodegenContext.model, clientCodegenContext.symbolProvider, operation).render(writer)
}
}
TopLevelErrorGenerator(config, operations).render(rustCrate)
TopLevelErrorGenerator(clientCodegenContext, operations).render(rustCrate)
rustCrate.withModule(RustModule.Config) { writer ->
ServiceConfigGenerator.withBaseBehavior(
config,
extraCustomizations = decorator.configCustomizations(config, listOf())
clientCodegenContext,
extraCustomizations = decorator.configCustomizations(clientCodegenContext, listOf())
).render(writer)
}

View File

@ -37,7 +37,8 @@ import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.stripOuter
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.RustCrate
import software.amazon.smithy.rust.codegen.smithy.RustSymbolProvider
@ -59,14 +60,14 @@ import software.amazon.smithy.rust.codegen.util.orNull
import software.amazon.smithy.rust.codegen.util.outputShape
import software.amazon.smithy.rust.codegen.util.toSnakeCase
class FluentClientDecorator : RustCodegenDecorator {
class FluentClientDecorator : RustCodegenDecorator<ClientCodegenContext> {
override val name: String = "FluentClient"
override val order: Byte = 0
private fun applies(codegenContext: CodegenContext): Boolean =
codegenContext.symbolProvider.config().codegenConfig.includeFluentClient
private fun applies(codegenContext: ClientCodegenContext): Boolean =
codegenContext.settings.codegenConfig.includeFluentClient
override fun extras(codegenContext: CodegenContext, rustCrate: RustCrate) {
override fun extras(codegenContext: ClientCodegenContext, rustCrate: RustCrate) {
if (!applies(codegenContext)) {
return
}
@ -80,7 +81,7 @@ class FluentClientDecorator : RustCodegenDecorator {
}
override fun libRsCustomizations(
codegenContext: CodegenContext,
codegenContext: ClientCodegenContext,
baseCustomizations: List<LibRsCustomization>
): List<LibRsCustomization> {
if (!applies(codegenContext)) {
@ -111,9 +112,9 @@ sealed class FluentClientSection(name: String) : Section(name) {
abstract class FluentClientCustomization : NamedSectionGenerator<FluentClientSection>()
class GenericFluentClient(codegenContext: CodegenContext) : FluentClientCustomization() {
private val moduleUseName = codegenContext.moduleUseName()
private val clientDep = CargoDependency.SmithyClient(codegenContext.runtimeConfig)
class GenericFluentClient(coreCodegenContext: CoreCodegenContext) : FluentClientCustomization() {
private val moduleUseName = coreCodegenContext.moduleUseName()
private val clientDep = CargoDependency.SmithyClient(coreCodegenContext.runtimeConfig)
private val codegenScope = arrayOf("client" to clientDep.asType())
override fun section(section: FluentClientSection): Writable {
return when (section) {
@ -283,12 +284,12 @@ class GenericFluentClient(codegenContext: CodegenContext) : FluentClientCustomiz
}
class FluentClientGenerator(
private val codegenContext: CodegenContext,
private val coreCodegenContext: CoreCodegenContext,
private val generics: FluentClientGenerics = FlexibleClientGenerics(
connectorDefault = null,
middlewareDefault = null,
retryDefault = CargoDependency.SmithyClient(codegenContext.runtimeConfig).asType().member("retry::Standard"),
client = CargoDependency.SmithyClient(codegenContext.runtimeConfig).asType()
retryDefault = CargoDependency.SmithyClient(coreCodegenContext.runtimeConfig).asType().member("retry::Standard"),
client = CargoDependency.SmithyClient(coreCodegenContext.runtimeConfig).asType()
),
private val customizations: List<FluentClientCustomization> = emptyList(),
) {
@ -303,13 +304,13 @@ class FluentClientGenerator(
)
}
private val serviceShape = codegenContext.serviceShape
private val serviceShape = coreCodegenContext.serviceShape
private val operations =
TopDownIndex.of(codegenContext.model).getContainedOperations(serviceShape).sortedBy { it.id }
private val symbolProvider = codegenContext.symbolProvider
private val model = codegenContext.model
private val clientDep = CargoDependency.SmithyClient(codegenContext.runtimeConfig)
private val runtimeConfig = codegenContext.runtimeConfig
TopDownIndex.of(coreCodegenContext.model).getContainedOperations(serviceShape).sortedBy { it.id }
private val symbolProvider = coreCodegenContext.symbolProvider
private val model = coreCodegenContext.model
private val clientDep = CargoDependency.SmithyClient(coreCodegenContext.runtimeConfig)
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val core = FluentClientCore(model)
fun render(crate: RustCrate) {
@ -516,7 +517,7 @@ class FluentClientGenerator(
.copy(name = "result::SdkError"),
"send_bounds" to generics.sendBounds(inputType, outputType, errorType)
)
PaginatorGenerator.paginatorType(codegenContext, generics, operation)?.also { paginatorType ->
PaginatorGenerator.paginatorType(coreCodegenContext, generics, operation)?.also { paginatorType ->
rustTemplate(
"""
/// Create a paginator for this request

View File

@ -15,7 +15,7 @@ import software.amazon.smithy.rust.codegen.rustlang.docs
import software.amazon.smithy.rust.codegen.rustlang.raw
import software.amazon.smithy.rust.codegen.rustlang.rustBlock
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.customize.NamedSectionGenerator
import software.amazon.smithy.rust.codegen.smithy.customize.Section
import software.amazon.smithy.rust.codegen.util.hasTrait
@ -111,9 +111,9 @@ typealias ConfigCustomization = NamedSectionGenerator<ServiceConfig>
class ServiceConfigGenerator(private val customizations: List<ConfigCustomization> = listOf()) {
companion object {
fun withBaseBehavior(codegenContext: CodegenContext, extraCustomizations: List<ConfigCustomization>): ServiceConfigGenerator {
fun withBaseBehavior(coreCodegenContext: CoreCodegenContext, extraCustomizations: List<ConfigCustomization>): ServiceConfigGenerator {
val baseFeatures = mutableListOf<ConfigCustomization>()
if (codegenContext.serviceShape.needsIdempotencyToken(codegenContext.model)) {
if (coreCodegenContext.serviceShape.needsIdempotencyToken(coreCodegenContext.model)) {
baseFeatures.add(IdempotencyTokenProviderCustomization())
}
return ServiceConfigGenerator(baseFeatures + extraCustomizations)

View File

@ -18,7 +18,7 @@ import software.amazon.smithy.rust.codegen.rustlang.documentShape
import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.rustBlock
import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.RustCrate
@ -37,15 +37,15 @@ import software.amazon.smithy.rust.codegen.smithy.RustCrate
* }
* ```
*/
class TopLevelErrorGenerator(codegenContext: CodegenContext, private val operations: List<OperationShape>) {
private val symbolProvider = codegenContext.symbolProvider
private val model = codegenContext.model
class TopLevelErrorGenerator(coreCodegenContext: CoreCodegenContext, private val operations: List<OperationShape>) {
private val symbolProvider = coreCodegenContext.symbolProvider
private val model = coreCodegenContext.model
private val allErrors = operations.flatMap { it.errors }.distinctBy { it.getName(codegenContext.serviceShape) }
.map { codegenContext.model.expectShape(it, StructureShape::class.java) }
.sortedBy { it.id.getName(codegenContext.serviceShape) }
private val allErrors = operations.flatMap { it.errors }.distinctBy { it.getName(coreCodegenContext.serviceShape) }
.map { coreCodegenContext.model.expectShape(it, StructureShape::class.java) }
.sortedBy { it.id.getName(coreCodegenContext.serviceShape) }
private val sdkError = CargoDependency.SmithyHttp(codegenContext.runtimeConfig).asType().member("result::SdkError")
private val sdkError = CargoDependency.SmithyHttp(coreCodegenContext.runtimeConfig).asType().member("result::SdkError")
fun render(crate: RustCrate) {
crate.withModule(RustModule.default("error_meta", visibility = Visibility.PRIVATE)) { writer ->
writer.renderDefinition()

View File

@ -35,7 +35,7 @@ import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.stripOuter
import software.amazon.smithy.rust.codegen.rustlang.withBlock
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.generators.CodegenTarget
import software.amazon.smithy.rust.codegen.smithy.generators.operationBuildError
@ -88,14 +88,14 @@ public enum class HttpMessageType {
*/
class HttpBindingGenerator(
private val protocol: Protocol,
codegenContext: CodegenContext,
coreCodegenContext: CoreCodegenContext,
private val operationShape: OperationShape
) {
private val runtimeConfig = codegenContext.runtimeConfig
private val symbolProvider = codegenContext.symbolProvider
private val target = codegenContext.target
private val model = codegenContext.model
private val service = codegenContext.serviceShape
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val symbolProvider = coreCodegenContext.symbolProvider
private val target = coreCodegenContext.target
private val model = coreCodegenContext.model
private val service = coreCodegenContext.serviceShape
private val index = HttpBindingIndex.of(model)
private val headerUtil = CargoDependency.SmithyHttp(runtimeConfig).asType().member("header")
private val defaultTimestampFormat = TimestampFormatTrait.Format.EPOCH_SECONDS

View File

@ -21,7 +21,7 @@ import software.amazon.smithy.rust.codegen.rustlang.autoDeref
import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.rustBlock
import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.generators.OperationBuildError
import software.amazon.smithy.rust.codegen.smithy.generators.operationBuildError
@ -53,16 +53,16 @@ fun SmithyPattern.rustFormatString(prefix: String, separator: String): String {
* headers & URL based on the HTTP trait implementation.
*/
class RequestBindingGenerator(
codegenContext: CodegenContext,
coreCodegenContext: CoreCodegenContext,
private val protocol: Protocol,
private val operationShape: OperationShape,
) {
private val model = codegenContext.model
private val model = coreCodegenContext.model
private val inputShape = operationShape.inputShape(model)
private val symbolProvider = codegenContext.symbolProvider
private val runtimeConfig = codegenContext.runtimeConfig
private val symbolProvider = coreCodegenContext.symbolProvider
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val httpTrait = protocol.httpBindingResolver.httpTrait(operationShape)
private val httpBindingGenerator = HttpBindingGenerator(protocol, codegenContext, operationShape)
private val httpBindingGenerator = HttpBindingGenerator(protocol, coreCodegenContext, operationShape)
private val index = HttpBindingIndex.of(model)
private val Encoder = CargoDependency.SmithyTypes(runtimeConfig).asType().member("primitive::Encoder")

View File

@ -7,17 +7,17 @@ package software.amazon.smithy.rust.codegen.smithy.generators.http
import software.amazon.smithy.model.shapes.OperationShape
import software.amazon.smithy.rust.codegen.rustlang.RustWriter
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.protocols.HttpBindingDescriptor
import software.amazon.smithy.rust.codegen.smithy.protocols.Protocol
class ResponseBindingGenerator(
protocol: Protocol,
codegenContext: CodegenContext,
coreCodegenContext: CoreCodegenContext,
operationShape: OperationShape
) {
private val httpBindingGenerator = HttpBindingGenerator(protocol, codegenContext, operationShape)
private val httpBindingGenerator = HttpBindingGenerator(protocol, coreCodegenContext, operationShape)
fun generateDeserializeHeaderFn(binding: HttpBindingDescriptor): RuntimeType =
httpBindingGenerator.generateDeserializeHeaderFn(binding)

View File

@ -18,7 +18,7 @@ import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.withBlock
import software.amazon.smithy.rust.codegen.rustlang.withBlockTemplate
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.customize.OperationCustomization
import software.amazon.smithy.rust.codegen.smithy.customize.OperationSection
@ -35,7 +35,7 @@ import software.amazon.smithy.rust.codegen.util.inputShape
/** Generates the `make_operation` function on input structs */
open class MakeOperationGenerator(
protected val codegenContext: CodegenContext,
protected val coreCodegenContext: CoreCodegenContext,
private val protocol: Protocol,
private val bodyGenerator: ProtocolPayloadGenerator,
private val public: Boolean,
@ -43,23 +43,23 @@ open class MakeOperationGenerator(
private val includeDefaultPayloadHeaders: Boolean,
private val functionName: String = "make_operation",
) {
protected val model = codegenContext.model
protected val runtimeConfig = codegenContext.runtimeConfig
protected val symbolProvider = codegenContext.symbolProvider
protected val model = coreCodegenContext.model
protected val runtimeConfig = coreCodegenContext.runtimeConfig
protected val symbolProvider = coreCodegenContext.symbolProvider
protected val httpBindingResolver = protocol.httpBindingResolver
private val sdkId =
codegenContext.serviceShape.getTrait<ServiceTrait>()?.sdkId?.lowercase()?.replace(" ", "")
?: codegenContext.serviceShape.id.getName(codegenContext.serviceShape)
coreCodegenContext.serviceShape.getTrait<ServiceTrait>()?.sdkId?.lowercase()?.replace(" ", "")
?: coreCodegenContext.serviceShape.id.getName(coreCodegenContext.serviceShape)
private val codegenScope = arrayOf(
"config" to RuntimeType.Config,
"header_util" to CargoDependency.SmithyHttp(runtimeConfig).asType().member("header"),
"http" to RuntimeType.http,
"HttpRequestBuilder" to RuntimeType.HttpRequestBuilder,
"OpBuildError" to codegenContext.runtimeConfig.operationBuildError(),
"OpBuildError" to coreCodegenContext.runtimeConfig.operationBuildError(),
"operation" to RuntimeType.operationModule(runtimeConfig),
"SdkBody" to RuntimeType.sdkBody(codegenContext.runtimeConfig)
"SdkBody" to RuntimeType.sdkBody(coreCodegenContext.runtimeConfig)
)
fun generateMakeOperation(
@ -160,7 +160,7 @@ open class MakeOperationGenerator(
open fun createHttpRequest(writer: RustWriter, operationShape: OperationShape) {
val httpBindingGenerator = RequestBindingGenerator(
codegenContext,
coreCodegenContext,
protocol,
operationShape
)

View File

@ -12,7 +12,7 @@ import software.amazon.smithy.rust.codegen.rustlang.RustWriter
import software.amazon.smithy.rust.codegen.rustlang.docLink
import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.rustBlock
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.customize.OperationCustomization
import software.amazon.smithy.rust.codegen.smithy.customize.OperationSection
@ -77,7 +77,7 @@ interface ProtocolTraitImplGenerator {
* Class providing scaffolding for HTTP based protocols that must build an HTTP request (headers / URL) and a body.
*/
open class ProtocolGenerator(
codegenContext: CodegenContext,
coreCodegenContext: CoreCodegenContext,
/**
* `Protocol` contains all protocol specific information. Each smithy protocol, e.g. RestJson, RestXml, etc. will
* have their own implementation of the protocol interface which defines how an input shape becomes and http::Request
@ -95,8 +95,8 @@ open class ProtocolGenerator(
*/
private val traitGenerator: ProtocolTraitImplGenerator,
) {
private val symbolProvider = codegenContext.symbolProvider
private val model = codegenContext.model
private val symbolProvider = coreCodegenContext.symbolProvider
private val model = coreCodegenContext.model
/**
* Render all code required for serializing requests and deserializing responses for the operation

View File

@ -30,7 +30,7 @@ import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.rustBlock
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.withBlock
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.generators.CodegenTarget
import software.amazon.smithy.rust.codegen.smithy.generators.Instantiator
@ -64,24 +64,24 @@ data class ProtocolSupport(
* Generate protocol tests for an operation
*/
class ProtocolTestGenerator(
private val codegenContext: CodegenContext,
private val coreCodegenContext: CoreCodegenContext,
private val protocolSupport: ProtocolSupport,
private val operationShape: OperationShape,
private val writer: RustWriter
) {
private val logger = Logger.getLogger(javaClass.name)
private val inputShape = operationShape.inputShape(codegenContext.model)
private val outputShape = operationShape.outputShape(codegenContext.model)
private val operationSymbol = codegenContext.symbolProvider.toSymbol(operationShape)
private val operationIndex = OperationIndex.of(codegenContext.model)
private val inputShape = operationShape.inputShape(coreCodegenContext.model)
private val outputShape = operationShape.outputShape(coreCodegenContext.model)
private val operationSymbol = coreCodegenContext.symbolProvider.toSymbol(operationShape)
private val operationIndex = OperationIndex.of(coreCodegenContext.model)
private val instantiator = with(codegenContext) {
private val instantiator = with(coreCodegenContext) {
Instantiator(symbolProvider, model, runtimeConfig, CodegenTarget.CLIENT)
}
private val codegenScope = arrayOf(
"SmithyHttp" to CargoDependency.SmithyHttp(codegenContext.runtimeConfig).asType(),
"SmithyHttp" to CargoDependency.SmithyHttp(coreCodegenContext.runtimeConfig).asType(),
"Http" to CargoDependency.Http.asType(),
"AssertEq" to CargoDependency.PrettyAssertions.asType().member("assert_eq!")
)
@ -138,7 +138,7 @@ class ProtocolTestGenerator(
private fun List<TestCase>.filterMatching(): List<TestCase> {
return if (RunOnly.isNullOrEmpty()) {
this.filter { testCase ->
testCase.testCase.protocol == codegenContext.protocol &&
testCase.testCase.protocol == coreCodegenContext.protocol &&
!DisableTests.contains(testCase.testCase.id)
}
} else {
@ -182,7 +182,7 @@ class ProtocolTestGenerator(
rust("/* test case disabled for this protocol (not yet supported) */")
return
}
val customToken = if (inputShape.findMemberWithTrait<IdempotencyTokenTrait>(codegenContext.model) != null) {
val customToken = if (inputShape.findMemberWithTrait<IdempotencyTokenTrait>(coreCodegenContext.model) != null) {
""".make_token("00000000-0000-4000-8000-000000000000")"""
} else ""
rust(
@ -248,7 +248,7 @@ class ProtocolTestGenerator(
}
private fun expectFail(testCase: HttpMessageTestCase): Boolean = ExpectFail.find {
it.id == testCase.id && it.action == testCase.action() && it.service == codegenContext.serviceShape.id.toString()
it.id == testCase.id && it.action == testCase.action() && it.service == coreCodegenContext.serviceShape.id.toString()
} != null
private fun RustWriter.renderHttpResponseTestCase(
@ -277,11 +277,11 @@ class ProtocolTestGenerator(
.body(#T::from(${testCase.body.orNull()?.dq()?.replace("#", "##") ?: "vec![]"}))
.unwrap();
""",
RuntimeType.sdkBody(runtimeConfig = codegenContext.runtimeConfig)
RuntimeType.sdkBody(runtimeConfig = coreCodegenContext.runtimeConfig)
)
write(
"let mut op_response = #T::new(http_response);",
RuntimeType.operationModule(codegenContext.runtimeConfig).member("Response")
RuntimeType.operationModule(coreCodegenContext.runtimeConfig).member("Response")
)
rustTemplate(
"""
@ -296,12 +296,12 @@ class ProtocolTestGenerator(
""",
"op" to operationSymbol,
"bytes" to RuntimeType.Bytes,
"parse_http_response" to CargoDependency.SmithyHttp(codegenContext.runtimeConfig).asType()
"parse_http_response" to CargoDependency.SmithyHttp(coreCodegenContext.runtimeConfig).asType()
.member("response::ParseHttpResponse"),
)
if (expectedShape.hasTrait<ErrorTrait>()) {
val errorSymbol = operationShape.errorSymbol(codegenContext.symbolProvider)
val errorVariant = codegenContext.symbolProvider.toSymbol(expectedShape).name
val errorSymbol = operationShape.errorSymbol(coreCodegenContext.symbolProvider)
val errorVariant = coreCodegenContext.symbolProvider.toSymbol(expectedShape).name
rust("""let parsed = parsed.expect_err("should be error response");""")
rustBlock("if let #TKind::$errorVariant(actual_error) = parsed.kind", errorSymbol) {
rustTemplate("#{AssertEq}(expected_output, actual_error);", *codegenScope)
@ -312,8 +312,8 @@ class ProtocolTestGenerator(
} else {
rust("let parsed = parsed.unwrap();")
outputShape.members().forEach { member ->
val memberName = codegenContext.symbolProvider.toMemberName(member)
if (member.isStreaming(codegenContext.model)) {
val memberName = coreCodegenContext.symbolProvider.toMemberName(member)
if (member.isStreaming(coreCodegenContext.model)) {
rustTemplate(
"""
#{AssertEq}(
@ -324,10 +324,10 @@ class ProtocolTestGenerator(
*codegenScope
)
} else {
when (codegenContext.model.expectShape(member.target)) {
when (coreCodegenContext.model.expectShape(member.target)) {
is DoubleShape, is FloatShape -> {
addUseImports(
RuntimeType.ProtocolTestHelper(codegenContext.runtimeConfig, "FloatEquals").toSymbol()
RuntimeType.ProtocolTestHelper(coreCodegenContext.runtimeConfig, "FloatEquals").toSymbol()
)
rust(
"""
@ -361,8 +361,8 @@ class ProtocolTestGenerator(
"#T(&body, ${
rustWriter.escape(body).dq()
}, #T::from(${(mediaType ?: "unknown").dq()}))",
RuntimeType.ProtocolTestHelper(codegenContext.runtimeConfig, "validate_body"),
RuntimeType.ProtocolTestHelper(codegenContext.runtimeConfig, "MediaType")
RuntimeType.ProtocolTestHelper(coreCodegenContext.runtimeConfig, "validate_body"),
RuntimeType.ProtocolTestHelper(coreCodegenContext.runtimeConfig, "MediaType")
)
}
}
@ -403,7 +403,7 @@ class ProtocolTestGenerator(
assertOk(rustWriter) {
write(
"#T($actualExpression, $variableName)",
RuntimeType.ProtocolTestHelper(codegenContext.runtimeConfig, "validate_headers")
RuntimeType.ProtocolTestHelper(coreCodegenContext.runtimeConfig, "validate_headers")
)
}
}
@ -457,7 +457,7 @@ class ProtocolTestGenerator(
assertOk(rustWriter) {
write(
"#T($actualExpression, $expectedVariableName)",
RuntimeType.ProtocolTestHelper(codegenContext.runtimeConfig, checkFunction)
RuntimeType.ProtocolTestHelper(coreCodegenContext.runtimeConfig, checkFunction)
)
}
}
@ -467,7 +467,7 @@ class ProtocolTestGenerator(
* for pretty prettying protocol test helper results
*/
private fun assertOk(rustWriter: RustWriter, inner: RustWriter.() -> Unit) {
rustWriter.write("#T(", RuntimeType.ProtocolTestHelper(codegenContext.runtimeConfig, "assert_ok"))
rustWriter.write("#T(", RuntimeType.ProtocolTestHelper(coreCodegenContext.runtimeConfig, "assert_ok"))
inner(rustWriter)
rustWriter.write(");")
}

View File

@ -17,7 +17,8 @@ import software.amazon.smithy.rust.codegen.rustlang.RustModule
import software.amazon.smithy.rust.codegen.rustlang.asType
import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.generators.protocol.ProtocolSupport
import software.amazon.smithy.rust.codegen.smithy.generators.serializationError
@ -39,12 +40,11 @@ sealed class AwsJsonVersion {
}
}
class AwsJsonFactory(private val version: AwsJsonVersion) : ProtocolGeneratorFactory<HttpBoundProtocolGenerator> {
override fun protocol(codegenContext: CodegenContext): Protocol = AwsJson(codegenContext, version)
class AwsJsonFactory(private val version: AwsJsonVersion) : ProtocolGeneratorFactory<HttpBoundProtocolGenerator, ClientCodegenContext> {
override fun protocol(codegenContext: ClientCodegenContext): Protocol = AwsJson(codegenContext, version)
override fun buildProtocolGenerator(codegenContext: CodegenContext): HttpBoundProtocolGenerator {
return HttpBoundProtocolGenerator(codegenContext, protocol(codegenContext))
}
override fun buildProtocolGenerator(codegenContext: ClientCodegenContext): HttpBoundProtocolGenerator =
HttpBoundProtocolGenerator(codegenContext, protocol(codegenContext))
override fun transformModel(model: Model): Model = model
@ -99,12 +99,12 @@ class AwsJsonHttpBindingResolver(
* customizes wraps [JsonSerializerGenerator] to add this functionality.
*/
class AwsJsonSerializerGenerator(
private val codegenContext: CodegenContext,
private val coreCodegenContext: CoreCodegenContext,
httpBindingResolver: HttpBindingResolver,
private val jsonSerializerGenerator: JsonSerializerGenerator =
JsonSerializerGenerator(codegenContext, httpBindingResolver, ::awsJsonFieldName)
JsonSerializerGenerator(coreCodegenContext, httpBindingResolver, ::awsJsonFieldName)
) : StructuredDataSerializerGenerator by jsonSerializerGenerator {
private val runtimeConfig = codegenContext.runtimeConfig
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val codegenScope = arrayOf(
"Error" to runtimeConfig.serializationError(),
"SdkBody" to RuntimeType.sdkBody(runtimeConfig),
@ -113,12 +113,12 @@ class AwsJsonSerializerGenerator(
override fun operationInputSerializer(operationShape: OperationShape): RuntimeType {
var serializer = jsonSerializerGenerator.operationInputSerializer(operationShape)
if (serializer == null) {
val inputShape = operationShape.inputShape(codegenContext.model)
val fnName = codegenContext.symbolProvider.serializeFunctionName(operationShape)
val inputShape = operationShape.inputShape(coreCodegenContext.model)
val fnName = coreCodegenContext.symbolProvider.serializeFunctionName(operationShape)
serializer = RuntimeType.forInlineFun(fnName, RustModule.private("operation_ser")) {
it.rustBlockTemplate(
"pub fn $fnName(_input: &#{target}) -> Result<#{SdkBody}, #{Error}>",
*codegenScope, "target" to codegenContext.symbolProvider.toSymbol(inputShape)
*codegenScope, "target" to coreCodegenContext.symbolProvider.toSymbol(inputShape)
) {
rustTemplate("""Ok(#{SdkBody}::from("{}"))""", *codegenScope)
}
@ -129,10 +129,10 @@ class AwsJsonSerializerGenerator(
}
open class AwsJson(
private val codegenContext: CodegenContext,
private val coreCodegenContext: CoreCodegenContext,
awsJsonVersion: AwsJsonVersion
) : Protocol {
private val runtimeConfig = codegenContext.runtimeConfig
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val errorScope = arrayOf(
"Bytes" to RuntimeType.Bytes,
"Error" to RuntimeType.GenericError(runtimeConfig),
@ -144,18 +144,18 @@ open class AwsJson(
private val jsonDeserModule = RustModule.private("json_deser")
override val httpBindingResolver: HttpBindingResolver =
AwsJsonHttpBindingResolver(codegenContext.model, awsJsonVersion)
AwsJsonHttpBindingResolver(coreCodegenContext.model, awsJsonVersion)
override val defaultTimestampFormat: TimestampFormatTrait.Format = TimestampFormatTrait.Format.EPOCH_SECONDS
override fun additionalRequestHeaders(operationShape: OperationShape): List<Pair<String, String>> =
listOf("x-amz-target" to "${codegenContext.serviceShape.id.name}.${operationShape.id.name}")
listOf("x-amz-target" to "${coreCodegenContext.serviceShape.id.name}.${operationShape.id.name}")
override fun structuredDataParser(operationShape: OperationShape): StructuredDataParserGenerator =
JsonParserGenerator(codegenContext, httpBindingResolver, ::awsJsonFieldName)
JsonParserGenerator(coreCodegenContext, httpBindingResolver, ::awsJsonFieldName)
override fun structuredDataSerializer(operationShape: OperationShape): StructuredDataSerializerGenerator =
AwsJsonSerializerGenerator(codegenContext, httpBindingResolver)
AwsJsonSerializerGenerator(coreCodegenContext, httpBindingResolver)
override fun parseHttpGenericError(operationShape: OperationShape): RuntimeType =
RuntimeType.forInlineFun("parse_http_generic_error", jsonDeserModule) { writer ->

View File

@ -17,7 +17,8 @@ import software.amazon.smithy.rust.codegen.rustlang.RustModule
import software.amazon.smithy.rust.codegen.rustlang.asType
import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.generators.protocol.ProtocolSupport
import software.amazon.smithy.rust.codegen.smithy.protocols.parse.AwsQueryParserGenerator
@ -26,10 +27,10 @@ import software.amazon.smithy.rust.codegen.smithy.protocols.serialize.AwsQuerySe
import software.amazon.smithy.rust.codegen.smithy.protocols.serialize.StructuredDataSerializerGenerator
import software.amazon.smithy.rust.codegen.util.getTrait
class AwsQueryFactory : ProtocolGeneratorFactory<HttpBoundProtocolGenerator> {
override fun protocol(codegenContext: CodegenContext): Protocol = AwsQueryProtocol(codegenContext)
class AwsQueryFactory : ProtocolGeneratorFactory<HttpBoundProtocolGenerator, ClientCodegenContext> {
override fun protocol(codegenContext: ClientCodegenContext): Protocol = AwsQueryProtocol(codegenContext)
override fun buildProtocolGenerator(codegenContext: CodegenContext): HttpBoundProtocolGenerator =
override fun buildProtocolGenerator(codegenContext: ClientCodegenContext): HttpBoundProtocolGenerator =
HttpBoundProtocolGenerator(codegenContext, protocol(codegenContext))
override fun transformModel(model: Model): Model = model
@ -64,8 +65,8 @@ class AwsQueryBindingResolver(private val model: Model) :
}
}
class AwsQueryProtocol(private val codegenContext: CodegenContext) : Protocol {
private val runtimeConfig = codegenContext.runtimeConfig
class AwsQueryProtocol(private val coreCodegenContext: CoreCodegenContext) : Protocol {
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val awsQueryErrors: RuntimeType = RuntimeType.wrappedXmlErrors(runtimeConfig)
private val errorScope = arrayOf(
"Bytes" to RuntimeType.Bytes,
@ -76,15 +77,15 @@ class AwsQueryProtocol(private val codegenContext: CodegenContext) : Protocol {
)
private val xmlDeserModule = RustModule.private("xml_deser")
override val httpBindingResolver: HttpBindingResolver = AwsQueryBindingResolver(codegenContext.model)
override val httpBindingResolver: HttpBindingResolver = AwsQueryBindingResolver(coreCodegenContext.model)
override val defaultTimestampFormat: TimestampFormatTrait.Format = TimestampFormatTrait.Format.DATE_TIME
override fun structuredDataParser(operationShape: OperationShape): StructuredDataParserGenerator =
AwsQueryParserGenerator(codegenContext, awsQueryErrors)
AwsQueryParserGenerator(coreCodegenContext, awsQueryErrors)
override fun structuredDataSerializer(operationShape: OperationShape): StructuredDataSerializerGenerator =
AwsQuerySerializerGenerator(codegenContext)
AwsQuerySerializerGenerator(coreCodegenContext)
override fun parseHttpGenericError(operationShape: OperationShape): RuntimeType =
RuntimeType.forInlineFun("parse_http_generic_error", xmlDeserModule) { writer ->

View File

@ -15,7 +15,8 @@ import software.amazon.smithy.rust.codegen.rustlang.RustModule
import software.amazon.smithy.rust.codegen.rustlang.asType
import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.generators.protocol.ProtocolSupport
import software.amazon.smithy.rust.codegen.smithy.protocols.parse.Ec2QueryParserGenerator
@ -23,10 +24,10 @@ import software.amazon.smithy.rust.codegen.smithy.protocols.parse.StructuredData
import software.amazon.smithy.rust.codegen.smithy.protocols.serialize.Ec2QuerySerializerGenerator
import software.amazon.smithy.rust.codegen.smithy.protocols.serialize.StructuredDataSerializerGenerator
class Ec2QueryFactory : ProtocolGeneratorFactory<HttpBoundProtocolGenerator> {
override fun protocol(codegenContext: CodegenContext): Protocol = Ec2QueryProtocol(codegenContext)
class Ec2QueryFactory : ProtocolGeneratorFactory<HttpBoundProtocolGenerator, ClientCodegenContext> {
override fun protocol(codegenContext: ClientCodegenContext): Protocol = Ec2QueryProtocol(codegenContext)
override fun buildProtocolGenerator(codegenContext: CodegenContext): HttpBoundProtocolGenerator =
override fun buildProtocolGenerator(codegenContext: ClientCodegenContext): HttpBoundProtocolGenerator =
HttpBoundProtocolGenerator(codegenContext, protocol(codegenContext))
override fun transformModel(model: Model): Model = model
@ -47,8 +48,8 @@ class Ec2QueryFactory : ProtocolGeneratorFactory<HttpBoundProtocolGenerator> {
}
}
class Ec2QueryProtocol(private val codegenContext: CodegenContext) : Protocol {
private val runtimeConfig = codegenContext.runtimeConfig
class Ec2QueryProtocol(private val coreCodegenContext: CoreCodegenContext) : Protocol {
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val ec2QueryErrors: RuntimeType = RuntimeType.ec2QueryErrors(runtimeConfig)
private val errorScope = arrayOf(
"Bytes" to RuntimeType.Bytes,
@ -60,7 +61,7 @@ class Ec2QueryProtocol(private val codegenContext: CodegenContext) : Protocol {
private val xmlDeserModule = RustModule.private("xml_deser")
override val httpBindingResolver: HttpBindingResolver = StaticHttpBindingResolver(
codegenContext.model,
coreCodegenContext.model,
HttpTrait.builder()
.code(200)
.method("POST")
@ -73,10 +74,10 @@ class Ec2QueryProtocol(private val codegenContext: CodegenContext) : Protocol {
override val defaultTimestampFormat: TimestampFormatTrait.Format = TimestampFormatTrait.Format.DATE_TIME
override fun structuredDataParser(operationShape: OperationShape): StructuredDataParserGenerator =
Ec2QueryParserGenerator(codegenContext, ec2QueryErrors)
Ec2QueryParserGenerator(coreCodegenContext, ec2QueryErrors)
override fun structuredDataSerializer(operationShape: OperationShape): StructuredDataSerializerGenerator =
Ec2QuerySerializerGenerator(codegenContext)
Ec2QuerySerializerGenerator(coreCodegenContext)
override fun parseHttpGenericError(operationShape: OperationShape): RuntimeType =
RuntimeType.forInlineFun("parse_http_generic_error", xmlDeserModule) { writer ->

View File

@ -20,7 +20,7 @@ import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.withBlock
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.generators.StructureGenerator
import software.amazon.smithy.rust.codegen.smithy.generators.builderSymbol
@ -41,28 +41,28 @@ import software.amazon.smithy.rust.codegen.util.outputShape
import software.amazon.smithy.rust.codegen.util.toSnakeCase
class HttpBoundProtocolGenerator(
codegenContext: CodegenContext,
coreCodegenContext: CoreCodegenContext,
protocol: Protocol,
) : ProtocolGenerator(
codegenContext,
coreCodegenContext,
protocol,
MakeOperationGenerator(
codegenContext,
coreCodegenContext,
protocol,
HttpBoundProtocolPayloadGenerator(codegenContext, protocol),
HttpBoundProtocolPayloadGenerator(coreCodegenContext, protocol),
public = true,
includeDefaultPayloadHeaders = true
),
HttpBoundProtocolTraitImplGenerator(codegenContext, protocol),
HttpBoundProtocolTraitImplGenerator(coreCodegenContext, protocol),
)
class HttpBoundProtocolTraitImplGenerator(
private val codegenContext: CodegenContext,
private val coreCodegenContext: CoreCodegenContext,
private val protocol: Protocol,
) : ProtocolTraitImplGenerator {
private val symbolProvider = codegenContext.symbolProvider
private val model = codegenContext.model
private val runtimeConfig = codegenContext.runtimeConfig
private val symbolProvider = coreCodegenContext.symbolProvider
private val model = coreCodegenContext.model
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val httpBindingResolver = protocol.httpBindingResolver
private val operationDeserModule = RustModule.private("operation_deser")
@ -278,7 +278,7 @@ class HttpBoundProtocolTraitImplGenerator(
bindings: List<HttpBindingDescriptor>,
errorSymbol: RuntimeType,
) {
val httpBindingGenerator = ResponseBindingGenerator(protocol, codegenContext, operationShape)
val httpBindingGenerator = ResponseBindingGenerator(protocol, coreCodegenContext, operationShape)
val structuredDataParser = protocol.structuredDataParser(operationShape)
Attribute.AllowUnusedMut.render(this)
rust("let mut output = #T::default();", outputShape.builderSymbol(symbolProvider))

View File

@ -23,7 +23,7 @@ import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.withBlock
import software.amazon.smithy.rust.codegen.rustlang.withBlockTemplate
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.generators.error.errorSymbol
import software.amazon.smithy.rust.codegen.smithy.generators.http.HttpMessageType
@ -44,14 +44,14 @@ import software.amazon.smithy.rust.codegen.util.outputShape
import software.amazon.smithy.rust.codegen.util.toSnakeCase
class HttpBoundProtocolPayloadGenerator(
codegenContext: CodegenContext,
coreCodegenContext: CoreCodegenContext,
private val protocol: Protocol,
private val httpMessageType: HttpMessageType = HttpMessageType.REQUEST
) : ProtocolPayloadGenerator {
private val symbolProvider = codegenContext.symbolProvider
private val model = codegenContext.model
private val runtimeConfig = codegenContext.runtimeConfig
private val target = codegenContext.target
private val symbolProvider = coreCodegenContext.symbolProvider
private val model = coreCodegenContext.model
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val target = coreCodegenContext.target
private val httpBindingResolver = protocol.httpBindingResolver
private val operationSerModule = RustModule.private("operation_ser")

View File

@ -20,7 +20,7 @@ import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.model.shapes.StructureShape
import software.amazon.smithy.model.traits.TimestampFormatTrait
import software.amazon.smithy.model.traits.Trait
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.RustSymbolProvider
import software.amazon.smithy.rust.codegen.smithy.generators.protocol.ProtocolGenerator
@ -76,21 +76,21 @@ interface Protocol {
fun parseEventStreamGenericError(operationShape: OperationShape): RuntimeType
}
typealias ProtocolMap = Map<ShapeId, ProtocolGeneratorFactory<ProtocolGenerator>>
typealias ProtocolMap<C> = Map<ShapeId, ProtocolGeneratorFactory<ProtocolGenerator, C>>
interface ProtocolGeneratorFactory<out T : ProtocolGenerator> {
fun protocol(codegenContext: CodegenContext): Protocol
fun buildProtocolGenerator(codegenContext: CodegenContext): T
interface ProtocolGeneratorFactory<out T : ProtocolGenerator, C : CoreCodegenContext> {
fun protocol(codegenContext: C): Protocol
fun buildProtocolGenerator(codegenContext: C): T
fun transformModel(model: Model): Model
fun symbolProvider(model: Model, base: RustSymbolProvider): RustSymbolProvider = base
fun support(): ProtocolSupport
}
class ProtocolLoader(private val supportedProtocols: ProtocolMap) {
class ProtocolLoader<C : CoreCodegenContext>(private val supportedProtocols: ProtocolMap<C>) {
fun protocolFor(
model: Model,
serviceShape: ServiceShape
): Pair<ShapeId, ProtocolGeneratorFactory<ProtocolGenerator>> {
): Pair<ShapeId, ProtocolGeneratorFactory<ProtocolGenerator, C>> {
val protocols: MutableMap<ShapeId, Trait> = ServiceIndex.of(model).getProtocols(serviceShape)
val matchingProtocols =
protocols.keys.mapNotNull { protocolId -> supportedProtocols[protocolId]?.let { protocolId to it } }

View File

@ -18,7 +18,8 @@ import software.amazon.smithy.rust.codegen.rustlang.CargoDependency
import software.amazon.smithy.rust.codegen.rustlang.RustModule
import software.amazon.smithy.rust.codegen.rustlang.asType
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.generators.protocol.ProtocolSupport
import software.amazon.smithy.rust.codegen.smithy.protocols.parse.JsonParserGenerator
@ -29,10 +30,10 @@ import software.amazon.smithy.rust.codegen.util.getTrait
import software.amazon.smithy.rust.codegen.util.hasTrait
import software.amazon.smithy.rust.codegen.util.outputShape
class RestJsonFactory : ProtocolGeneratorFactory<HttpBoundProtocolGenerator> {
override fun protocol(codegenContext: CodegenContext): Protocol = RestJson(codegenContext)
class RestJsonFactory : ProtocolGeneratorFactory<HttpBoundProtocolGenerator, ClientCodegenContext> {
override fun protocol(codegenContext: ClientCodegenContext): Protocol = RestJson(codegenContext)
override fun buildProtocolGenerator(codegenContext: CodegenContext): HttpBoundProtocolGenerator =
override fun buildProtocolGenerator(codegenContext: ClientCodegenContext): HttpBoundProtocolGenerator =
HttpBoundProtocolGenerator(codegenContext, RestJson(codegenContext))
override fun transformModel(model: Model): Model = model
@ -86,8 +87,8 @@ class RestJsonHttpBindingResolver(
}
}
class RestJson(private val codegenContext: CodegenContext) : Protocol {
private val runtimeConfig = codegenContext.runtimeConfig
class RestJson(private val coreCodegenContext: CoreCodegenContext) : Protocol {
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val errorScope = arrayOf(
"Bytes" to RuntimeType.Bytes,
"Error" to RuntimeType.GenericError(runtimeConfig),
@ -99,7 +100,7 @@ class RestJson(private val codegenContext: CodegenContext) : Protocol {
private val jsonDeserModule = RustModule.private("json_deser")
override val httpBindingResolver: HttpBindingResolver =
RestJsonHttpBindingResolver(codegenContext.model, ProtocolContentTypes.consistent("application/json"))
RestJsonHttpBindingResolver(coreCodegenContext.model, ProtocolContentTypes.consistent("application/json"))
override val defaultTimestampFormat: TimestampFormatTrait.Format = TimestampFormatTrait.Format.EPOCH_SECONDS
@ -111,10 +112,10 @@ class RestJson(private val codegenContext: CodegenContext) : Protocol {
listOf("x-amzn-errortype" to errorShape.id.name)
override fun structuredDataParser(operationShape: OperationShape): StructuredDataParserGenerator =
JsonParserGenerator(codegenContext, httpBindingResolver, ::restJsonFieldName)
JsonParserGenerator(coreCodegenContext, httpBindingResolver, ::restJsonFieldName)
override fun structuredDataSerializer(operationShape: OperationShape): StructuredDataSerializerGenerator =
JsonSerializerGenerator(codegenContext, httpBindingResolver, ::restJsonFieldName)
JsonSerializerGenerator(coreCodegenContext, httpBindingResolver, ::restJsonFieldName)
override fun parseHttpGenericError(operationShape: OperationShape): RuntimeType =
RuntimeType.forInlineFun("parse_http_generic_error", jsonDeserModule) { writer ->

View File

@ -14,7 +14,8 @@ import software.amazon.smithy.rust.codegen.rustlang.RustModule
import software.amazon.smithy.rust.codegen.rustlang.asType
import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.generators.protocol.ProtocolSupport
import software.amazon.smithy.rust.codegen.smithy.protocols.parse.RestXmlParserGenerator
@ -23,11 +24,13 @@ import software.amazon.smithy.rust.codegen.smithy.protocols.serialize.Structured
import software.amazon.smithy.rust.codegen.smithy.protocols.serialize.XmlBindingTraitSerializerGenerator
import software.amazon.smithy.rust.codegen.util.expectTrait
class RestXmlFactory(private val generator: (CodegenContext) -> Protocol = { RestXml(it) }) :
ProtocolGeneratorFactory<HttpBoundProtocolGenerator> {
override fun protocol(codegenContext: CodegenContext): Protocol = generator(codegenContext)
class RestXmlFactory(
private val generator: (ClientCodegenContext) -> Protocol = { RestXml(it) }
) : ProtocolGeneratorFactory<HttpBoundProtocolGenerator, ClientCodegenContext> {
override fun buildProtocolGenerator(codegenContext: CodegenContext): HttpBoundProtocolGenerator =
override fun protocol(codegenContext: ClientCodegenContext): Protocol = generator(codegenContext)
override fun buildProtocolGenerator(codegenContext: ClientCodegenContext): HttpBoundProtocolGenerator =
HttpBoundProtocolGenerator(codegenContext, protocol(codegenContext))
override fun transformModel(model: Model): Model = model
@ -48,9 +51,9 @@ class RestXmlFactory(private val generator: (CodegenContext) -> Protocol = { Res
}
}
open class RestXml(private val codegenContext: CodegenContext) : Protocol {
private val restXml = codegenContext.serviceShape.expectTrait<RestXmlTrait>()
private val runtimeConfig = codegenContext.runtimeConfig
open class RestXml(private val coreCodegenContext: CoreCodegenContext) : Protocol {
private val restXml = coreCodegenContext.serviceShape.expectTrait<RestXmlTrait>()
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val errorScope = arrayOf(
"Bytes" to RuntimeType.Bytes,
"Error" to RuntimeType.GenericError(runtimeConfig),
@ -66,17 +69,17 @@ open class RestXml(private val codegenContext: CodegenContext) : Protocol {
}
override val httpBindingResolver: HttpBindingResolver =
HttpTraitHttpBindingResolver(codegenContext.model, ProtocolContentTypes.consistent("application/xml"))
HttpTraitHttpBindingResolver(coreCodegenContext.model, ProtocolContentTypes.consistent("application/xml"))
override val defaultTimestampFormat: TimestampFormatTrait.Format =
TimestampFormatTrait.Format.DATE_TIME
override fun structuredDataParser(operationShape: OperationShape): StructuredDataParserGenerator {
return RestXmlParserGenerator(codegenContext, restXmlErrors)
return RestXmlParserGenerator(coreCodegenContext, restXmlErrors)
}
override fun structuredDataSerializer(operationShape: OperationShape): StructuredDataSerializerGenerator {
return XmlBindingTraitSerializerGenerator(codegenContext, httpBindingResolver)
return XmlBindingTraitSerializerGenerator(coreCodegenContext, httpBindingResolver)
}
override fun parseHttpGenericError(operationShape: OperationShape): RuntimeType =

View File

@ -6,7 +6,7 @@
package software.amazon.smithy.rust.codegen.smithy.protocols.parse
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
/**
@ -25,14 +25,14 @@ import software.amazon.smithy.rust.codegen.smithy.RuntimeType
* of the response parsing, but it overrides [operationParser] to add the protocol differences.
*/
class AwsQueryParserGenerator(
codegenContext: CodegenContext,
coreCodegenContext: CoreCodegenContext,
xmlErrors: RuntimeType,
private val xmlBindingTraitParserGenerator: XmlBindingTraitParserGenerator =
XmlBindingTraitParserGenerator(
codegenContext,
coreCodegenContext,
xmlErrors
) { context, inner ->
val operationName = codegenContext.symbolProvider.toSymbol(context.shape).name
val operationName = coreCodegenContext.symbolProvider.toSymbol(context.shape).name
val responseWrapperName = operationName + "Response"
val resultWrapperName = operationName + "Result"
rustTemplate(

View File

@ -6,7 +6,7 @@
package software.amazon.smithy.rust.codegen.smithy.protocols.parse
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
/**
@ -23,14 +23,14 @@ import software.amazon.smithy.rust.codegen.smithy.RuntimeType
* of the response parsing, but it overrides [operationParser] to add the protocol differences.
*/
class Ec2QueryParserGenerator(
codegenContext: CodegenContext,
coreCodegenContext: CoreCodegenContext,
xmlErrors: RuntimeType,
private val xmlBindingTraitParserGenerator: XmlBindingTraitParserGenerator =
XmlBindingTraitParserGenerator(
codegenContext,
coreCodegenContext,
xmlErrors
) { context, inner ->
val operationName = codegenContext.symbolProvider.toSymbol(context.shape).name
val operationName = coreCodegenContext.symbolProvider.toSymbol(context.shape).name
val responseWrapperName = operationName + "Response"
rustTemplate(
"""

View File

@ -33,7 +33,7 @@ import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.withBlock
import software.amazon.smithy.rust.codegen.rustlang.withBlockTemplate
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.canUseDefault
import software.amazon.smithy.rust.codegen.smithy.generators.CodegenTarget
@ -54,15 +54,15 @@ import software.amazon.smithy.rust.codegen.util.outputShape
import software.amazon.smithy.utils.StringUtils
class JsonParserGenerator(
codegenContext: CodegenContext,
private val coreCodegenContext: CoreCodegenContext,
private val httpBindingResolver: HttpBindingResolver,
/** Function that maps a MemberShape into a JSON field name */
private val jsonName: (MemberShape) -> String,
) : StructuredDataParserGenerator {
private val model = codegenContext.model
private val symbolProvider = codegenContext.symbolProvider
private val runtimeConfig = codegenContext.runtimeConfig
private val target = codegenContext.target
private val model = coreCodegenContext.model
private val symbolProvider = coreCodegenContext.symbolProvider
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val target = coreCodegenContext.target
private val smithyJson = CargoDependency.smithyJson(runtimeConfig).asType()
private val jsonDeserModule = RustModule.private("json_deser")
private val codegenScope = arrayOf(

View File

@ -6,15 +6,15 @@
package software.amazon.smithy.rust.codegen.smithy.protocols.parse
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
class RestXmlParserGenerator(
codegenContext: CodegenContext,
coreCodegenContext: CoreCodegenContext,
xmlErrors: RuntimeType,
private val xmlBindingTraitParserGenerator: XmlBindingTraitParserGenerator =
XmlBindingTraitParserGenerator(
codegenContext,
coreCodegenContext,
xmlErrors
) { context, inner ->
val shapeName = context.outputShapeName

View File

@ -37,7 +37,7 @@ import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.withBlock
import software.amazon.smithy.rust.codegen.rustlang.withBlockTemplate
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.generators.StructureGenerator
import software.amazon.smithy.rust.codegen.smithy.generators.UnionGenerator
@ -66,7 +66,7 @@ data class OperationWrapperContext(
)
class XmlBindingTraitParserGenerator(
codegenContext: CodegenContext,
coreCodegenContext: CoreCodegenContext,
private val xmlErrors: RuntimeType,
private val writeOperationWrapper: RustWriter.(OperationWrapperContext, OperationInnerWriteable) -> Unit,
) : StructuredDataParserGenerator {
@ -92,12 +92,12 @@ class XmlBindingTraitParserGenerator(
*/
data class Ctx(val tag: String, val accum: String?)
private val symbolProvider = codegenContext.symbolProvider
private val smithyXml = CargoDependency.smithyXml(codegenContext.runtimeConfig).asType()
private val symbolProvider = coreCodegenContext.symbolProvider
private val smithyXml = CargoDependency.smithyXml(coreCodegenContext.runtimeConfig).asType()
private val xmlError = smithyXml.member("decode::XmlError")
private val scopedDecoder = smithyXml.member("decode::ScopedDecoder")
private val runtimeConfig = codegenContext.runtimeConfig
private val runtimeConfig = coreCodegenContext.runtimeConfig
// The symbols we want all the time
private val codegenScope = arrayOf(
@ -109,10 +109,10 @@ class XmlBindingTraitParserGenerator(
"ScopedDecoder" to scopedDecoder,
"aws_smithy_types" to CargoDependency.SmithyTypes(runtimeConfig).asType()
)
private val model = codegenContext.model
private val model = coreCodegenContext.model
private val index = HttpBindingIndex.of(model)
private val xmlIndex = XmlNameIndex.of(model)
private val target = codegenContext.target
private val target = coreCodegenContext.target
private val xmlDeserModule = RustModule.private("xml_deser")
/**

View File

@ -10,11 +10,11 @@ import software.amazon.smithy.model.shapes.OperationShape
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.model.traits.XmlFlattenedTrait
import software.amazon.smithy.model.traits.XmlNameTrait
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.util.getTrait
class AwsQuerySerializerGenerator(codegenContext: CodegenContext) : QuerySerializerGenerator(codegenContext) {
class AwsQuerySerializerGenerator(coreCodegenContext: CoreCodegenContext) : QuerySerializerGenerator(coreCodegenContext) {
override val protocolName: String get() = "AWS Query"
override fun MemberShape.queryKeyName(prioritizedFallback: String?): String =

View File

@ -10,12 +10,12 @@ import software.amazon.smithy.model.shapes.MemberShape
import software.amazon.smithy.model.shapes.OperationShape
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.model.traits.XmlNameTrait
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.util.getTrait
import software.amazon.smithy.utils.StringUtils
class Ec2QuerySerializerGenerator(codegenContext: CodegenContext) : QuerySerializerGenerator(codegenContext) {
class Ec2QuerySerializerGenerator(coreCodegenContext: CoreCodegenContext) : QuerySerializerGenerator(coreCodegenContext) {
override val protocolName: String get() = "EC2 Query"
override fun MemberShape.queryKeyName(prioritizedFallback: String?): String =

View File

@ -31,7 +31,7 @@ import software.amazon.smithy.rust.codegen.rustlang.rustBlock
import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.withBlock
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.RustSymbolProvider
import software.amazon.smithy.rust.codegen.smithy.customize.NamedSectionGenerator
@ -65,7 +65,7 @@ sealed class JsonSection(name: String) : Section(name) {
typealias JsonCustomization = NamedSectionGenerator<JsonSection>
class JsonSerializerGenerator(
codegenContext: CodegenContext,
coreCodegenContext: CoreCodegenContext,
private val httpBindingResolver: HttpBindingResolver,
/** Function that maps a MemberShape into a JSON field name */
private val jsonName: (MemberShape) -> String,
@ -145,10 +145,10 @@ class JsonSerializerGenerator(
val shape: StructureShape,
)
private val model = codegenContext.model
private val symbolProvider = codegenContext.symbolProvider
private val target = codegenContext.target
private val runtimeConfig = codegenContext.runtimeConfig
private val model = coreCodegenContext.model
private val symbolProvider = coreCodegenContext.symbolProvider
private val target = coreCodegenContext.target
private val runtimeConfig = coreCodegenContext.runtimeConfig
private val smithyTypes = CargoDependency.SmithyTypes(runtimeConfig).asType()
private val smithyJson = CargoDependency.smithyJson(runtimeConfig).asType()
private val codegenScope = arrayOf(

Some files were not shown because too many files have changed in this diff Show More