From 86bddca689cd70a70fafecd2cf911e2d01c1e6cf Mon Sep 17 00:00:00 2001 From: John DiSanti Date: Fri, 17 Feb 2023 13:19:45 -0800 Subject: [PATCH] Move inputs, outputs, and op errors into operation modules (#2394) --- aws/sdk/build.gradle.kts | 3 +- .../client/smithy/ClientCodegenVisitor.kt | 7 +- .../codegen/client/smithy/ClientRustModule.kt | 71 +++++++++++++++++-- .../client/smithy/RustClientCodegenPlugin.kt | 10 +-- .../smithy/generators/PaginatorGenerator.kt | 2 +- .../smithy/generators/error/ErrorGenerator.kt | 2 +- .../error/OperationErrorGenerator.kt | 8 +-- .../codegen/client/testutil/TestHelpers.kt | 4 +- .../smithy/EventStreamSymbolProviderTest.kt | 4 +- .../core/rustlang/RustReservedWords.kt | 4 +- .../core/smithy/EventStreamSymbolProvider.kt | 9 --- .../codegen/core/smithy/RustSymbolProvider.kt | 42 ++++++++--- .../smithy/StreamingTraitSymbolProvider.kt | 11 +-- .../core/smithy/SymbolMetadataProvider.kt | 1 - .../rust/codegen/core/smithy/SymbolVisitor.kt | 9 ++- .../smithy/generators/BuilderGenerator.kt | 2 +- .../generators/error/ErrorImplGenerator.kt | 2 +- .../rust/codegen/core/testutil/TestHelpers.kt | 34 +++++---- .../core/rustlang/RustReservedWordsTest.kt | 12 ++-- .../codegen/core}/smithy/SymbolVisitorTest.kt | 19 +++-- .../smithy/generators/BuilderGeneratorTest.kt | 33 ++------- .../smithy/PythonServerSymbolProvider.kt | 8 +-- .../smithy/RustServerCodegenPythonPlugin.kt | 14 ++-- .../ConstrainedShapeSymbolMetadataProvider.kt | 2 - .../smithy/ConstrainedShapeSymbolProvider.kt | 4 +- .../ConstraintViolationSymbolProvider.kt | 2 - .../DeriveEqAndHashSymbolMetadataProvider.kt | 2 - .../PubCrateConstrainedShapeSymbolProvider.kt | 4 +- .../server/smithy/RustServerCodegenPlugin.kt | 16 ++--- .../codegen/server/smithy/ServerRustModule.kt | 15 ++-- .../server/smithy/ServerSymbolProviders.kt | 4 +- .../UnconstrainedShapeSymbolProvider.kt | 4 +- .../ConstrainedShapeSymbolProviderTest.kt | 2 +- ...riveEqAndHashSymbolMetadataProviderTest.kt | 4 +- 34 files changed, 208 insertions(+), 162 deletions(-) rename {codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client => codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core}/smithy/SymbolVisitorTest.kt (92%) diff --git a/aws/sdk/build.gradle.kts b/aws/sdk/build.gradle.kts index e2b3d0b72b..9d049f6116 100644 --- a/aws/sdk/build.gradle.kts +++ b/aws/sdk/build.gradle.kts @@ -97,7 +97,8 @@ fun generateSmithyBuild(services: AwsServices): String { "codegen": { "includeFluentClient": false, "renameErrors": false, - "eventStreamAllowList": [$eventStreamAllowListMembers] + "eventStreamAllowList": [$eventStreamAllowListMembers], + "enableNewCrateOrganizationScheme": false }, "service": "${service.service}", "module": "$moduleName", diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientCodegenVisitor.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientCodegenVisitor.kt index 889674babc..39cb33d4c5 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientCodegenVisitor.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientCodegenVisitor.kt @@ -71,7 +71,10 @@ class ClientCodegenVisitor( runtimeConfig = settings.runtimeConfig, renameExceptions = settings.codegenConfig.renameExceptions, nullabilityCheckMode = NullableIndex.CheckMode.CLIENT_ZERO_VALUE_V1, - moduleProvider = ClientModuleProvider, + moduleProvider = when (settings.codegenConfig.enableNewCrateOrganizationScheme) { + true -> ClientModuleProvider + else -> OldModuleSchemeClientModuleProvider + }, ) val baseModel = baselineTransform(context.model) val untransformedService = settings.getService(baseModel) @@ -263,7 +266,7 @@ class ClientCodegenVisitor( * Generate errors for operation shapes */ override fun operationShape(shape: OperationShape) { - rustCrate.withModule(ClientRustModule.Error) { + rustCrate.withModule(symbolProvider.moduleForOperationError(shape)) { OperationErrorGenerator( model, symbolProvider, diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientRustModule.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientRustModule.kt index 53fe9c6921..326fd28a80 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientRustModule.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientRustModule.kt @@ -5,16 +5,23 @@ package software.amazon.smithy.rust.codegen.client.smithy +import software.amazon.smithy.model.Model import software.amazon.smithy.model.shapes.OperationShape import software.amazon.smithy.model.shapes.Shape import software.amazon.smithy.model.shapes.StructureShape import software.amazon.smithy.model.shapes.UnionShape import software.amazon.smithy.model.traits.ErrorTrait import software.amazon.smithy.rust.codegen.core.rustlang.RustModule +import software.amazon.smithy.rust.codegen.core.rustlang.RustReservedWords import software.amazon.smithy.rust.codegen.core.smithy.ModuleProvider +import software.amazon.smithy.rust.codegen.core.smithy.ModuleProviderContext +import software.amazon.smithy.rust.codegen.core.smithy.contextName import software.amazon.smithy.rust.codegen.core.smithy.traits.SyntheticInputTrait import software.amazon.smithy.rust.codegen.core.smithy.traits.SyntheticOutputTrait +import software.amazon.smithy.rust.codegen.core.util.UNREACHABLE +import software.amazon.smithy.rust.codegen.core.util.getTrait import software.amazon.smithy.rust.codegen.core.util.hasTrait +import software.amazon.smithy.rust.codegen.core.util.toSnakeCase /** * Modules for code generated client crates. @@ -22,6 +29,7 @@ import software.amazon.smithy.rust.codegen.core.util.hasTrait object ClientRustModule { /** crate::client */ val client = Client.self + object Client { /** crate::client */ val self = RustModule.public("client", "Client and fluent builders for calling the service.") @@ -40,7 +48,55 @@ object ClientRustModule { } object ClientModuleProvider : ModuleProvider { - override fun moduleForShape(shape: Shape): RustModule.LeafModule = when (shape) { + override fun moduleForShape(context: ModuleProviderContext, shape: Shape): RustModule.LeafModule = when (shape) { + is OperationShape -> perOperationModule(context, shape) + is StructureShape -> when { + shape.hasTrait() -> ClientRustModule.Error + shape.hasTrait() -> perOperationModule(context, shape) + shape.hasTrait() -> perOperationModule(context, shape) + else -> ClientRustModule.Model + } + + else -> ClientRustModule.Model + } + + override fun moduleForOperationError( + context: ModuleProviderContext, + operation: OperationShape, + ): RustModule.LeafModule = perOperationModule(context, operation) + + override fun moduleForEventStreamError( + context: ModuleProviderContext, + eventStream: UnionShape, + ): RustModule.LeafModule = ClientRustModule.Error + + private fun Shape.findOperation(model: Model): OperationShape { + val inputTrait = getTrait() + val outputTrait = getTrait() + return when { + this is OperationShape -> this + inputTrait != null -> model.expectShape(inputTrait.operation, OperationShape::class.java) + outputTrait != null -> model.expectShape(outputTrait.operation, OperationShape::class.java) + else -> UNREACHABLE("this is only called with compatible shapes") + } + } + + private fun perOperationModule(context: ModuleProviderContext, shape: Shape): RustModule.LeafModule { + val operationShape = shape.findOperation(context.model) + val contextName = operationShape.contextName(context.serviceShape) + val operationModuleName = + RustReservedWords.escapeIfNeeded(contextName.toSnakeCase()) + return RustModule.public( + operationModuleName, + parent = ClientRustModule.Operation, + documentation = "Types for the `$contextName` operation.", + ) + } +} + +// TODO(CrateReorganization): Remove this provider +object OldModuleSchemeClientModuleProvider : ModuleProvider { + override fun moduleForShape(context: ModuleProviderContext, shape: Shape): RustModule.LeafModule = when (shape) { is OperationShape -> ClientRustModule.Operation is StructureShape -> when { shape.hasTrait() -> ClientRustModule.Error @@ -48,12 +104,17 @@ object ClientModuleProvider : ModuleProvider { shape.hasTrait() -> ClientRustModule.Output else -> ClientRustModule.Model } + else -> ClientRustModule.Model } - override fun moduleForOperationError(operation: OperationShape): RustModule.LeafModule = - ClientRustModule.Error + override fun moduleForOperationError( + context: ModuleProviderContext, + operation: OperationShape, + ): RustModule.LeafModule = ClientRustModule.Error - override fun moduleForEventStreamError(eventStream: UnionShape): RustModule.LeafModule = - ClientRustModule.Error + override fun moduleForEventStreamError( + context: ModuleProviderContext, + eventStream: UnionShape, + ): RustModule.LeafModule = ClientRustModule.Error } diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/RustClientCodegenPlugin.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/RustClientCodegenPlugin.kt index d50f1d421a..c1b35d10bd 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/RustClientCodegenPlugin.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/RustClientCodegenPlugin.kt @@ -77,15 +77,15 @@ class RustClientCodegenPlugin : ClientDecoratableBuildPlugin() { fun baseSymbolProvider(model: Model, serviceShape: ServiceShape, rustSymbolProviderConfig: RustSymbolProviderConfig) = SymbolVisitor(model, serviceShape = serviceShape, config = rustSymbolProviderConfig) // Generate different types for EventStream shapes (e.g. transcribe streaming) - .let { EventStreamSymbolProvider(rustSymbolProviderConfig.runtimeConfig, it, model, CodegenTarget.CLIENT) } + .let { EventStreamSymbolProvider(rustSymbolProviderConfig.runtimeConfig, it, CodegenTarget.CLIENT) } // Generate `ByteStream` instead of `Blob` for streaming binary shapes (e.g. S3 GetObject) - .let { StreamingShapeSymbolProvider(it, model) } + .let { StreamingShapeSymbolProvider(it) } // Add Rust attributes (like `#[derive(PartialEq)]`) to generated shapes - .let { BaseSymbolMetadataProvider(it, model, additionalAttributes = listOf(NonExhaustive)) } + .let { BaseSymbolMetadataProvider(it, additionalAttributes = listOf(NonExhaustive)) } // Streaming shapes need different derives (e.g. they cannot derive `PartialEq`) - .let { StreamingShapeMetadataProvider(it, model) } + .let { StreamingShapeMetadataProvider(it) } // Rename shapes that clash with Rust reserved words & and other SDK specific features e.g. `send()` cannot // be the name of an operation input - .let { RustReservedWordSymbolProvider(it, model) } + .let { RustReservedWordSymbolProvider(it) } } } diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/PaginatorGenerator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/PaginatorGenerator.kt index cbde592f02..4c668bc8ea 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/PaginatorGenerator.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/PaginatorGenerator.kt @@ -69,7 +69,7 @@ class PaginatorGenerator private constructor( } private val paginatorName = "${operation.id.name.toPascalCase()}Paginator" - private val runtimeConfig = symbolProvider.config().runtimeConfig + private val runtimeConfig = symbolProvider.config.runtimeConfig private val idx = PaginatedIndex.of(model) private val paginationInfo = idx.getPaginationInfo(service, operation).orNull() ?: PANIC("failed to load pagination info") diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/error/ErrorGenerator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/error/ErrorGenerator.kt index ffd4c9a287..feddf95a2f 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/error/ErrorGenerator.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/error/ErrorGenerator.kt @@ -36,7 +36,7 @@ class ErrorGenerator( private val error: ErrorTrait, private val implCustomizations: List, ) { - private val runtimeConfig = symbolProvider.config().runtimeConfig + private val runtimeConfig = symbolProvider.config.runtimeConfig fun render() { val symbol = symbolProvider.toSymbol(shape) diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/error/OperationErrorGenerator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/error/OperationErrorGenerator.kt index 5d44738a2c..d9ef055a37 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/error/OperationErrorGenerator.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/error/OperationErrorGenerator.kt @@ -49,9 +49,9 @@ class OperationErrorGenerator( private val operationOrEventStream: Shape, private val customizations: List, ) { - private val runtimeConfig = symbolProvider.config().runtimeConfig + private val runtimeConfig = symbolProvider.config.runtimeConfig private val symbol = symbolProvider.toSymbol(operationOrEventStream) - private val errorMetadata = errorMetadata(symbolProvider.config().runtimeConfig) + private val errorMetadata = errorMetadata(symbolProvider.config.runtimeConfig) private val createUnhandledError = RuntimeType.smithyHttp(runtimeConfig).resolve("result::CreateUnhandledError") @@ -148,10 +148,10 @@ class OperationErrorGenerator( writer.writeCustomizations(customizations, ErrorSection.OperationErrorAdditionalTraitImpls(errorSymbol, errors)) - val retryErrorKindT = RuntimeType.retryErrorKind(symbolProvider.config().runtimeConfig) + val retryErrorKindT = RuntimeType.retryErrorKind(symbolProvider.config.runtimeConfig) writer.rustBlock( "impl #T for ${errorSymbol.name}", - RuntimeType.provideErrorKind(symbolProvider.config().runtimeConfig), + RuntimeType.provideErrorKind(symbolProvider.config.runtimeConfig), ) { rustBlock("fn code(&self) -> Option<&str>") { rust("#T::code(self)", RuntimeType.provideErrorMetadataTrait(runtimeConfig)) diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/testutil/TestHelpers.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/testutil/TestHelpers.kt index ce0034841c..a381bc8af3 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/testutil/TestHelpers.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/testutil/TestHelpers.kt @@ -11,8 +11,8 @@ import software.amazon.smithy.model.node.ObjectNode import software.amazon.smithy.model.shapes.ServiceShape import software.amazon.smithy.model.shapes.ShapeId import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenConfig -import software.amazon.smithy.rust.codegen.client.smithy.ClientModuleProvider import software.amazon.smithy.rust.codegen.client.smithy.ClientRustSettings +import software.amazon.smithy.rust.codegen.client.smithy.OldModuleSchemeClientModuleProvider import software.amazon.smithy.rust.codegen.client.smithy.RustClientCodegenPlugin import software.amazon.smithy.rust.codegen.core.smithy.CodegenContext import software.amazon.smithy.rust.codegen.core.smithy.CodegenTarget @@ -53,7 +53,7 @@ val ClientTestRustSymbolProviderConfig = RustSymbolProviderConfig( runtimeConfig = TestRuntimeConfig, renameExceptions = true, nullabilityCheckMode = NullableIndex.CheckMode.CLIENT_ZERO_VALUE_V1, - moduleProvider = ClientModuleProvider, + moduleProvider = OldModuleSchemeClientModuleProvider, ) fun testSymbolProvider(model: Model, serviceShape: ServiceShape? = null): RustSymbolProvider = diff --git a/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/EventStreamSymbolProviderTest.kt b/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/EventStreamSymbolProviderTest.kt index d26cee721f..15e40ae838 100644 --- a/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/EventStreamSymbolProviderTest.kt +++ b/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/EventStreamSymbolProviderTest.kt @@ -46,7 +46,7 @@ class EventStreamSymbolProviderTest { ) val service = model.expectShape(ShapeId.from("test#TestService")) as ServiceShape - val provider = EventStreamSymbolProvider(TestRuntimeConfig, SymbolVisitor(model, service, ClientTestRustSymbolProviderConfig), model, CodegenTarget.CLIENT) + val provider = EventStreamSymbolProvider(TestRuntimeConfig, SymbolVisitor(model, service, ClientTestRustSymbolProviderConfig), CodegenTarget.CLIENT) // Look up the synthetic input/output rather than the original input/output val inputStream = model.expectShape(ShapeId.from("test.synthetic#TestOperationInput\$inputStream")) as MemberShape @@ -82,7 +82,7 @@ class EventStreamSymbolProviderTest { ) val service = model.expectShape(ShapeId.from("test#TestService")) as ServiceShape - val provider = EventStreamSymbolProvider(TestRuntimeConfig, SymbolVisitor(model, service, ClientTestRustSymbolProviderConfig), model, CodegenTarget.CLIENT) + val provider = EventStreamSymbolProvider(TestRuntimeConfig, SymbolVisitor(model, service, ClientTestRustSymbolProviderConfig), CodegenTarget.CLIENT) // Look up the synthetic input/output rather than the original input/output val inputStream = model.expectShape(ShapeId.from("test.synthetic#TestOperationInput\$inputStream")) as MemberShape diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/rustlang/RustReservedWords.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/rustlang/RustReservedWords.kt index 34a4382302..4e36582abc 100644 --- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/rustlang/RustReservedWords.kt +++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/rustlang/RustReservedWords.kt @@ -8,7 +8,6 @@ package software.amazon.smithy.rust.codegen.core.rustlang import software.amazon.smithy.codegen.core.ReservedWordSymbolProvider import software.amazon.smithy.codegen.core.ReservedWords import software.amazon.smithy.codegen.core.Symbol -import software.amazon.smithy.model.Model import software.amazon.smithy.model.shapes.MemberShape import software.amazon.smithy.model.shapes.Shape import software.amazon.smithy.model.shapes.StructureShape @@ -23,8 +22,7 @@ import software.amazon.smithy.rust.codegen.core.util.letIf import software.amazon.smithy.rust.codegen.core.util.orNull import software.amazon.smithy.rust.codegen.core.util.toPascalCase -class RustReservedWordSymbolProvider(private val base: RustSymbolProvider, private val model: Model) : - WrappingSymbolProvider(base) { +class RustReservedWordSymbolProvider(private val base: RustSymbolProvider) : WrappingSymbolProvider(base) { private val internal = ReservedWordSymbolProvider.builder().symbolProvider(base).memberReservedWords(RustReservedWords).build() diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/EventStreamSymbolProvider.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/EventStreamSymbolProvider.kt index 9a75974d24..6eeab26d65 100644 --- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/EventStreamSymbolProvider.kt +++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/EventStreamSymbolProvider.kt @@ -6,13 +6,10 @@ package software.amazon.smithy.rust.codegen.core.smithy import software.amazon.smithy.codegen.core.Symbol -import software.amazon.smithy.model.Model import software.amazon.smithy.model.shapes.MemberShape import software.amazon.smithy.model.shapes.OperationShape import software.amazon.smithy.model.shapes.Shape -import software.amazon.smithy.model.shapes.UnionShape import software.amazon.smithy.rust.codegen.core.rustlang.CargoDependency -import software.amazon.smithy.rust.codegen.core.rustlang.RustModule import software.amazon.smithy.rust.codegen.core.rustlang.RustType import software.amazon.smithy.rust.codegen.core.rustlang.render import software.amazon.smithy.rust.codegen.core.rustlang.stripOuter @@ -24,18 +21,12 @@ import software.amazon.smithy.rust.codegen.core.util.isEventStream import software.amazon.smithy.rust.codegen.core.util.isInputEventStream import software.amazon.smithy.rust.codegen.core.util.isOutputEventStream -fun UnionShape.eventStreamErrorSymbol(symbolProvider: RustSymbolProvider): RuntimeType { - val unionSymbol = symbolProvider.toSymbol(this) - return RustModule.Error.toType().resolve("${unionSymbol.name}Error") -} - /** * Wrapping symbol provider to wrap modeled types with the aws-smithy-http Event Stream send/receive types. */ class EventStreamSymbolProvider( private val runtimeConfig: RuntimeConfig, base: RustSymbolProvider, - private val model: Model, private val target: CodegenTarget, ) : WrappingSymbolProvider(base) { override fun toSymbol(shape: Shape): Symbol { diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/RustSymbolProvider.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/RustSymbolProvider.kt index 7b8b115d76..f6b7762df1 100644 --- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/RustSymbolProvider.kt +++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/RustSymbolProvider.kt @@ -7,9 +7,11 @@ package software.amazon.smithy.rust.codegen.core.smithy import software.amazon.smithy.codegen.core.Symbol import software.amazon.smithy.codegen.core.SymbolProvider +import software.amazon.smithy.model.Model import software.amazon.smithy.model.knowledge.NullableIndex import software.amazon.smithy.model.shapes.MemberShape import software.amazon.smithy.model.shapes.OperationShape +import software.amazon.smithy.model.shapes.ServiceShape import software.amazon.smithy.model.shapes.Shape import software.amazon.smithy.model.shapes.UnionShape import software.amazon.smithy.model.traits.EnumDefinition @@ -18,15 +20,19 @@ import software.amazon.smithy.rust.codegen.core.rustlang.RustModule /** * SymbolProvider interface that carries both the inner configuration and a function to produce an enum variant name. */ -interface RustSymbolProvider : SymbolProvider, ModuleProvider { - fun config(): RustSymbolProviderConfig +interface RustSymbolProvider : SymbolProvider { + val model: Model + val moduleProviderContext: ModuleProviderContext + val config: RustSymbolProviderConfig + fun toEnumVariantName(definition: EnumDefinition): MaybeRenamed? - override fun moduleForShape(shape: Shape): RustModule.LeafModule = config().moduleProvider.moduleForShape(shape) - override fun moduleForOperationError(operation: OperationShape): RustModule.LeafModule = - config().moduleProvider.moduleForOperationError(operation) - override fun moduleForEventStreamError(eventStream: UnionShape): RustModule.LeafModule = - config().moduleProvider.moduleForEventStreamError(eventStream) + fun moduleForShape(shape: Shape): RustModule.LeafModule = + config.moduleProvider.moduleForShape(moduleProviderContext, shape) + fun moduleForOperationError(operation: OperationShape): RustModule.LeafModule = + config.moduleProvider.moduleForOperationError(moduleProviderContext, operation) + fun moduleForEventStreamError(eventStream: UnionShape): RustModule.LeafModule = + config.moduleProvider.moduleForEventStreamError(moduleProviderContext, eventStream) /** Returns the symbol for an operation error */ fun symbolForOperationError(operation: OperationShape): Symbol @@ -35,18 +41,29 @@ interface RustSymbolProvider : SymbolProvider, ModuleProvider { fun symbolForEventStreamError(eventStream: UnionShape): Symbol } +/** + * Module providers can't use the full CodegenContext since they're invoked from + * inside the SymbolVisitor, which is created before CodegenContext is created. + */ +data class ModuleProviderContext( + val model: Model, + val serviceShape: ServiceShape?, +) + +fun CodegenContext.toModuleProviderContext(): ModuleProviderContext = ModuleProviderContext(model, serviceShape) + /** * Provider for RustModules so that the symbol provider knows where to organize things. */ interface ModuleProvider { /** Returns the module for a shape */ - fun moduleForShape(shape: Shape): RustModule.LeafModule + fun moduleForShape(context: ModuleProviderContext, shape: Shape): RustModule.LeafModule /** Returns the module for an operation error */ - fun moduleForOperationError(operation: OperationShape): RustModule.LeafModule + fun moduleForOperationError(context: ModuleProviderContext, operation: OperationShape): RustModule.LeafModule /** Returns the module for an event stream error */ - fun moduleForEventStreamError(eventStream: UnionShape): RustModule.LeafModule + fun moduleForEventStreamError(context: ModuleProviderContext, eventStream: UnionShape): RustModule.LeafModule } /** @@ -63,7 +80,10 @@ data class RustSymbolProviderConfig( * Default delegator to enable easily decorating another symbol provider. */ open class WrappingSymbolProvider(private val base: RustSymbolProvider) : RustSymbolProvider { - override fun config(): RustSymbolProviderConfig = base.config() + override val model: Model get() = base.model + override val moduleProviderContext: ModuleProviderContext get() = base.moduleProviderContext + override val config: RustSymbolProviderConfig get() = base.config + override fun toEnumVariantName(definition: EnumDefinition): MaybeRenamed? = base.toEnumVariantName(definition) override fun toSymbol(shape: Shape): Symbol = base.toSymbol(shape) override fun toMemberName(shape: MemberShape): String = base.toMemberName(shape) diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/StreamingTraitSymbolProvider.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/StreamingTraitSymbolProvider.kt index 3e1d082627..ab4db2c644 100644 --- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/StreamingTraitSymbolProvider.kt +++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/StreamingTraitSymbolProvider.kt @@ -6,7 +6,6 @@ package software.amazon.smithy.rust.codegen.core.smithy import software.amazon.smithy.codegen.core.Symbol -import software.amazon.smithy.model.Model import software.amazon.smithy.model.shapes.BlobShape import software.amazon.smithy.model.shapes.ListShape import software.amazon.smithy.model.shapes.MapShape @@ -26,8 +25,7 @@ import software.amazon.smithy.rust.codegen.core.util.isStreaming /** * Wrapping symbol provider to change `Blob` to `ByteStream` when it targets a streaming member */ -class StreamingShapeSymbolProvider(private val base: RustSymbolProvider, private val model: Model) : - WrappingSymbolProvider(base) { +class StreamingShapeSymbolProvider(private val base: RustSymbolProvider) : WrappingSymbolProvider(base) { override fun toSymbol(shape: Shape): Symbol { val initial = base.toSymbol(shape) // We are only targeting member shapes @@ -44,7 +42,7 @@ class StreamingShapeSymbolProvider(private val base: RustSymbolProvider, private // We are only targeting streaming blobs return if (target is BlobShape && shape.isStreaming(model)) { - RuntimeType.byteStream(config().runtimeConfig).toSymbol().toBuilder().setDefault(Default.RustDefault).build() + RuntimeType.byteStream(config.runtimeConfig).toSymbol().toBuilder().setDefault(Default.RustDefault).build() } else { base.toSymbol(shape) } @@ -59,10 +57,7 @@ class StreamingShapeSymbolProvider(private val base: RustSymbolProvider, private * * Note that since streaming members can only be used on the root shape, this can only impact input and output shapes. */ -class StreamingShapeMetadataProvider( - private val base: RustSymbolProvider, - private val model: Model, -) : SymbolMetadataProvider(base) { +class StreamingShapeMetadataProvider(private val base: RustSymbolProvider) : SymbolMetadataProvider(base) { override fun structureMeta(structureShape: StructureShape): RustMetadata { val baseMetadata = base.toSymbol(structureShape).expectRustMetadata() return if (structureShape.hasStreamingMember(model)) { diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/SymbolMetadataProvider.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/SymbolMetadataProvider.kt index 276e7017ce..62b84f2387 100644 --- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/SymbolMetadataProvider.kt +++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/SymbolMetadataProvider.kt @@ -94,7 +94,6 @@ fun containerDefaultMetadata( */ class BaseSymbolMetadataProvider( base: RustSymbolProvider, - private val model: Model, private val additionalAttributes: List, ) : SymbolMetadataProvider(base) { diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/SymbolVisitor.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/SymbolVisitor.kt index 1261689a63..b8a6f34573 100644 --- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/SymbolVisitor.kt +++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/SymbolVisitor.kt @@ -105,13 +105,12 @@ fun Shape.contextName(serviceShape: ServiceShape?): String { * derives for a given shape. */ open class SymbolVisitor( - private val model: Model, + override val model: Model, private val serviceShape: ServiceShape?, - private val config: RustSymbolProviderConfig, -) : RustSymbolProvider, - ShapeVisitor { + override val config: RustSymbolProviderConfig, +) : RustSymbolProvider, ShapeVisitor { + override val moduleProviderContext = ModuleProviderContext(model, serviceShape) private val nullableIndex = NullableIndex.of(model) - override fun config(): RustSymbolProviderConfig = config override fun toSymbol(shape: Shape): Symbol { return shape.accept(this) diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/BuilderGenerator.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/BuilderGenerator.kt index deff9c1fb6..000e2845e4 100644 --- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/BuilderGenerator.kt +++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/BuilderGenerator.kt @@ -135,7 +135,7 @@ class BuilderGenerator( } } - private val runtimeConfig = symbolProvider.config().runtimeConfig + private val runtimeConfig = symbolProvider.config.runtimeConfig private val members: List = shape.allMembers.values.toList() private val structureSymbol = symbolProvider.toSymbol(shape) private val builderSymbol = shape.builderSymbol(symbolProvider) diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/error/ErrorImplGenerator.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/error/ErrorImplGenerator.kt index 93bfb3d9b2..692bf32aab 100644 --- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/error/ErrorImplGenerator.kt +++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/error/ErrorImplGenerator.kt @@ -90,7 +90,7 @@ class ErrorImplGenerator( private val error: ErrorTrait, private val customizations: List, ) { - private val runtimeConfig = symbolProvider.config().runtimeConfig + private val runtimeConfig = symbolProvider.config.runtimeConfig fun render(forWhom: CodegenTarget = CodegenTarget.CLIENT) { val symbol = symbolProvider.toSymbol(shape) diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/testutil/TestHelpers.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/testutil/TestHelpers.kt index 023f30236e..18c935d707 100644 --- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/testutil/TestHelpers.kt +++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/testutil/TestHelpers.kt @@ -25,6 +25,7 @@ import software.amazon.smithy.rust.codegen.core.smithy.CodegenTarget import software.amazon.smithy.rust.codegen.core.smithy.CoreCodegenConfig import software.amazon.smithy.rust.codegen.core.smithy.CoreRustSettings import software.amazon.smithy.rust.codegen.core.smithy.ModuleProvider +import software.amazon.smithy.rust.codegen.core.smithy.ModuleProviderContext import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig import software.amazon.smithy.rust.codegen.core.smithy.RuntimeCrateLocation import software.amazon.smithy.rust.codegen.core.smithy.RustSymbolProvider @@ -58,19 +59,28 @@ private object CodegenCoreTestModules { val OperationsTestModule = RustModule.public("test_operation", documentation = "Test operation module") object TestModuleProvider : ModuleProvider { - override fun moduleForShape(shape: Shape): RustModule.LeafModule = when (shape) { - is OperationShape -> OperationsTestModule - is StructureShape -> when { - shape.hasTrait() -> ErrorsTestModule - shape.hasTrait() -> InputsTestModule - shape.hasTrait() -> OutputsTestModule + override fun moduleForShape(context: ModuleProviderContext, shape: Shape): RustModule.LeafModule = + when (shape) { + is OperationShape -> OperationsTestModule + is StructureShape -> when { + shape.hasTrait() -> ErrorsTestModule + shape.hasTrait() -> InputsTestModule + shape.hasTrait() -> OutputsTestModule + else -> ModelsTestModule + } + else -> ModelsTestModule } - else -> ModelsTestModule - } - override fun moduleForOperationError(operation: OperationShape): RustModule.LeafModule = ErrorsTestModule - override fun moduleForEventStreamError(eventStream: UnionShape): RustModule.LeafModule = ErrorsTestModule + override fun moduleForOperationError( + context: ModuleProviderContext, + operation: OperationShape, + ): RustModule.LeafModule = ErrorsTestModule + + override fun moduleForEventStreamError( + context: ModuleProviderContext, + eventStream: UnionShape, + ): RustModule.LeafModule = ErrorsTestModule } } @@ -117,8 +127,8 @@ internal fun testSymbolProvider(model: Model): RustSymbolProvider = SymbolVisito model, ServiceShape.builder().version("test").id("test#Service").build(), TestRustSymbolProviderConfig, -).let { BaseSymbolMetadataProvider(it, model, additionalAttributes = listOf(Attribute.NonExhaustive)) } - .let { RustReservedWordSymbolProvider(it, model) } +).let { BaseSymbolMetadataProvider(it, additionalAttributes = listOf(Attribute.NonExhaustive)) } + .let { RustReservedWordSymbolProvider(it) } // Intentionally only visible to codegen-core since the other modules have their own contexts internal fun testCodegenContext( diff --git a/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/rustlang/RustReservedWordsTest.kt b/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/rustlang/RustReservedWordsTest.kt index ebdf9cdc47..d9c0574c3f 100644 --- a/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/rustlang/RustReservedWordsTest.kt +++ b/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/rustlang/RustReservedWordsTest.kt @@ -8,12 +8,14 @@ package software.amazon.smithy.rust.codegen.core.rustlang import io.kotest.matchers.shouldBe import org.junit.jupiter.api.Test import software.amazon.smithy.codegen.core.Symbol +import software.amazon.smithy.model.Model import software.amazon.smithy.model.shapes.MemberShape import software.amazon.smithy.model.shapes.OperationShape import software.amazon.smithy.model.shapes.Shape import software.amazon.smithy.model.shapes.UnionShape import software.amazon.smithy.model.traits.EnumDefinition import software.amazon.smithy.rust.codegen.core.smithy.MaybeRenamed +import software.amazon.smithy.rust.codegen.core.smithy.ModuleProviderContext import software.amazon.smithy.rust.codegen.core.smithy.RustSymbolProvider import software.amazon.smithy.rust.codegen.core.smithy.RustSymbolProviderConfig import software.amazon.smithy.rust.codegen.core.testutil.asSmithyModel @@ -22,8 +24,10 @@ import software.amazon.smithy.rust.codegen.core.util.orNull import software.amazon.smithy.rust.codegen.core.util.toPascalCase internal class RustReservedWordSymbolProviderTest { - class Stub : RustSymbolProvider { - override fun config(): RustSymbolProviderConfig = PANIC() + class Stub(override val model: Model) : RustSymbolProvider { + override val moduleProviderContext: ModuleProviderContext get() = PANIC() + override val config: RustSymbolProviderConfig get() = PANIC() + override fun symbolForOperationError(operation: OperationShape): Symbol = PANIC() override fun symbolForEventStreamError(eventStream: UnionShape): Symbol = PANIC() @@ -44,7 +48,7 @@ internal class RustReservedWordSymbolProviderTest { async: String } """.trimMargin().asSmithyModel() - val provider = RustReservedWordSymbolProvider(Stub(), model) + val provider = RustReservedWordSymbolProvider(Stub(model)) provider.toMemberName( MemberShape.builder().id("namespace#container\$async").target("namespace#Integer").build(), ) shouldBe "r##async" @@ -68,7 +72,7 @@ internal class RustReservedWordSymbolProviderTest { private fun expectEnumRename(original: String, expected: MaybeRenamed) { val model = "namespace foo".asSmithyModel() - val provider = RustReservedWordSymbolProvider(Stub(), model) + val provider = RustReservedWordSymbolProvider(Stub(model)) provider.toEnumVariantName(EnumDefinition.builder().name(original).value("foo").build()) shouldBe expected } } diff --git a/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/SymbolVisitorTest.kt b/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/smithy/SymbolVisitorTest.kt similarity index 92% rename from codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/SymbolVisitorTest.kt rename to codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/smithy/SymbolVisitorTest.kt index f1dc61e337..3c47ca4f67 100644 --- a/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/SymbolVisitorTest.kt +++ b/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/smithy/SymbolVisitorTest.kt @@ -3,12 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -package software.amazon.smithy.rust.codegen.client.smithy +package software.amazon.smithy.rust.codegen.core.smithy import io.kotest.matchers.collections.shouldContain import io.kotest.matchers.collections.shouldNotBeEmpty import io.kotest.matchers.shouldBe -import io.kotest.matchers.string.shouldContain import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test @@ -26,12 +25,10 @@ import software.amazon.smithy.model.shapes.StringShape import software.amazon.smithy.model.shapes.StructureShape import software.amazon.smithy.model.traits.ErrorTrait import software.amazon.smithy.model.traits.SparseTrait -import software.amazon.smithy.rust.codegen.client.testutil.testSymbolProvider import software.amazon.smithy.rust.codegen.core.rustlang.RustType import software.amazon.smithy.rust.codegen.core.rustlang.render -import software.amazon.smithy.rust.codegen.core.smithy.isOptional -import software.amazon.smithy.rust.codegen.core.smithy.rustType import software.amazon.smithy.rust.codegen.core.testutil.asSmithyModel +import software.amazon.smithy.rust.codegen.core.testutil.testSymbolProvider class SymbolVisitorTest { private fun Symbol.referenceClosure(): List { @@ -54,8 +51,8 @@ class SymbolVisitorTest { val provider: SymbolProvider = testSymbolProvider(model) val sym = provider.toSymbol(struct) sym.rustType().render(false) shouldBe "MyStruct" - sym.definitionFile shouldContain ClientRustModule.Model.definitionFile() - sym.namespace shouldBe "crate::model" + sym.definitionFile shouldBe "src/test_model.rs" + sym.namespace shouldBe "crate::test_model" } @Test @@ -74,7 +71,7 @@ class SymbolVisitorTest { val provider: SymbolProvider = testSymbolProvider(model) val sym = provider.toSymbol(struct) sym.rustType().render(false) shouldBe "TerribleError" - sym.definitionFile shouldContain ClientRustModule.Error.definitionFile() + sym.definitionFile shouldBe "src/test_error.rs" } @Test @@ -98,8 +95,8 @@ class SymbolVisitorTest { val provider: SymbolProvider = testSymbolProvider(model) val sym = provider.toSymbol(shape) sym.rustType().render(false) shouldBe "StandardUnit" - sym.definitionFile shouldContain ClientRustModule.Model.definitionFile() - sym.namespace shouldBe "crate::model" + sym.definitionFile shouldBe "src/test_model.rs" + sym.namespace shouldBe "crate::test_model" } @DisplayName("Creates primitives") @@ -257,7 +254,7 @@ class SymbolVisitorTest { } """.asSmithyModel() val symbol = testSymbolProvider(model).toSymbol(model.expectShape(ShapeId.from("smithy.example#PutObject"))) - symbol.definitionFile shouldBe ClientRustModule.Operation.definitionFile() + symbol.definitionFile shouldBe "src/test_operation.rs" symbol.name shouldBe "PutObject" } } diff --git a/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/BuilderGeneratorTest.kt b/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/BuilderGeneratorTest.kt index 5fb91663ef..d3f0232720 100644 --- a/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/BuilderGeneratorTest.kt +++ b/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/BuilderGeneratorTest.kt @@ -7,24 +7,17 @@ package software.amazon.smithy.rust.codegen.core.smithy.generators import org.junit.jupiter.api.Test import software.amazon.smithy.codegen.core.Symbol -import software.amazon.smithy.model.shapes.MemberShape -import software.amazon.smithy.model.shapes.OperationShape import software.amazon.smithy.model.shapes.Shape -import software.amazon.smithy.model.shapes.UnionShape -import software.amazon.smithy.model.traits.EnumDefinition import software.amazon.smithy.rust.codegen.core.rustlang.Attribute.Companion.AllowDeprecated import software.amazon.smithy.rust.codegen.core.rustlang.implBlock import software.amazon.smithy.rust.codegen.core.rustlang.rust import software.amazon.smithy.rust.codegen.core.smithy.Default -import software.amazon.smithy.rust.codegen.core.smithy.MaybeRenamed -import software.amazon.smithy.rust.codegen.core.smithy.RustSymbolProvider -import software.amazon.smithy.rust.codegen.core.smithy.RustSymbolProviderConfig +import software.amazon.smithy.rust.codegen.core.smithy.WrappingSymbolProvider import software.amazon.smithy.rust.codegen.core.smithy.setDefault import software.amazon.smithy.rust.codegen.core.testutil.TestWorkspace import software.amazon.smithy.rust.codegen.core.testutil.compileAndTest import software.amazon.smithy.rust.codegen.core.testutil.testSymbolProvider import software.amazon.smithy.rust.codegen.core.testutil.unitTest -import software.amazon.smithy.rust.codegen.core.util.PANIC internal class BuilderGeneratorTest { private val model = StructureGeneratorTest.model @@ -64,27 +57,11 @@ internal class BuilderGeneratorTest { @Test fun `generate fallible builders`() { val baseProvider = testSymbolProvider(StructureGeneratorTest.model) - val provider = - object : RustSymbolProvider { - override fun config(): RustSymbolProviderConfig { - return baseProvider.config() - } - - override fun toEnumVariantName(definition: EnumDefinition): MaybeRenamed? { - return baseProvider.toEnumVariantName(definition) - } - - override fun toSymbol(shape: Shape?): Symbol { - return baseProvider.toSymbol(shape).toBuilder().setDefault(Default.NoDefault).build() - } - - override fun symbolForOperationError(operation: OperationShape): Symbol = PANIC() - override fun symbolForEventStreamError(eventStream: UnionShape): Symbol = PANIC() - - override fun toMemberName(shape: MemberShape?): String { - return baseProvider.toMemberName(shape) - } + val provider = object : WrappingSymbolProvider(baseProvider) { + override fun toSymbol(shape: Shape): Symbol { + return baseProvider.toSymbol(shape).toBuilder().setDefault(Default.NoDefault).build() } + } val project = TestWorkspace.testProject(provider) project.moduleFor(StructureGeneratorTest.struct) { AllowDeprecated.render(this) diff --git a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/PythonServerSymbolProvider.kt b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/PythonServerSymbolProvider.kt index e8974f46bc..5e8f858371 100644 --- a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/PythonServerSymbolProvider.kt +++ b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/PythonServerSymbolProvider.kt @@ -44,11 +44,11 @@ import software.amazon.smithy.rust.codegen.core.util.isStreaming * `aws_smithy_http_server_python::types`. */ class PythonServerSymbolVisitor( - private val model: Model, + model: Model, serviceShape: ServiceShape?, config: RustSymbolProviderConfig, ) : SymbolVisitor(model, serviceShape, config) { - private val runtimeConfig = config().runtimeConfig + private val runtimeConfig = config.runtimeConfig override fun toSymbol(shape: Shape): Symbol { val initial = shape.accept(this) @@ -68,7 +68,7 @@ class PythonServerSymbolVisitor( // For example a TimestampShape doesn't become a different symbol when streaming is involved, but BlobShape // become a ByteStream. return if (target is BlobShape && shape.isStreaming(model)) { - PythonServerRuntimeType.byteStream(config().runtimeConfig).toSymbol() + PythonServerRuntimeType.byteStream(config.runtimeConfig).toSymbol() } else { initial } @@ -95,7 +95,7 @@ class PythonServerSymbolVisitor( * * Note that since streaming members can only be used on the root shape, this can only impact input and output shapes. */ -class PythonStreamingShapeMetadataProvider(private val base: RustSymbolProvider, private val model: Model) : SymbolMetadataProvider(base) { +class PythonStreamingShapeMetadataProvider(private val base: RustSymbolProvider) : SymbolMetadataProvider(base) { override fun structureMeta(structureShape: StructureShape): RustMetadata { val baseMetadata = base.toSymbol(structureShape).expectRustMetadata() return if (structureShape.hasStreamingMember(model)) { diff --git a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/RustServerCodegenPythonPlugin.kt b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/RustServerCodegenPythonPlugin.kt index 8642e4049b..9631367024 100644 --- a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/RustServerCodegenPythonPlugin.kt +++ b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/RustServerCodegenPythonPlugin.kt @@ -79,19 +79,19 @@ class RustServerCodegenPythonPlugin : SmithyBuildPlugin { // Generate public constrained types for directly constrained shapes. // In the Python server project, this is only done to generate constrained types for simple shapes (e.g. // a `string` shape with the `length` trait), but these always remain `pub(crate)`. - .let { if (constrainedTypes) ConstrainedShapeSymbolProvider(it, model, serviceShape, constrainedTypes) else it } + .let { if (constrainedTypes) ConstrainedShapeSymbolProvider(it, serviceShape, constrainedTypes) else it } // Generate different types for EventStream shapes (e.g. transcribe streaming) - .let { EventStreamSymbolProvider(rustSymbolProviderConfig.runtimeConfig, it, model, CodegenTarget.SERVER) } + .let { EventStreamSymbolProvider(rustSymbolProviderConfig.runtimeConfig, it, CodegenTarget.SERVER) } // Add Rust attributes (like `#[derive(PartialEq)]`) to generated shapes - .let { BaseSymbolMetadataProvider(it, model, additionalAttributes = listOf()) } + .let { BaseSymbolMetadataProvider(it, additionalAttributes = listOf()) } // Constrained shapes generate newtypes that need the same derives we place on types generated from aggregate shapes. - .let { ConstrainedShapeSymbolMetadataProvider(it, model, constrainedTypes) } + .let { ConstrainedShapeSymbolMetadataProvider(it, constrainedTypes) } // Streaming shapes need different derives (e.g. they cannot derive Eq) - .let { PythonStreamingShapeMetadataProvider(it, model) } + .let { PythonStreamingShapeMetadataProvider(it) } // Derive `Eq` and `Hash` if possible. - .let { DeriveEqAndHashSymbolMetadataProvider(it, model) } + .let { DeriveEqAndHashSymbolMetadataProvider(it) } // Rename shapes that clash with Rust reserved words & and other SDK specific features e.g. `send()` cannot // be the name of an operation input - .let { RustReservedWordSymbolProvider(it, model) } + .let { RustReservedWordSymbolProvider(it) } } } diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ConstrainedShapeSymbolMetadataProvider.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ConstrainedShapeSymbolMetadataProvider.kt index 01e8255ccc..0c83795f2f 100644 --- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ConstrainedShapeSymbolMetadataProvider.kt +++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ConstrainedShapeSymbolMetadataProvider.kt @@ -5,7 +5,6 @@ package software.amazon.smithy.rust.codegen.server.smithy -import software.amazon.smithy.model.Model import software.amazon.smithy.model.shapes.BlobShape import software.amazon.smithy.model.shapes.ListShape import software.amazon.smithy.model.shapes.MapShape @@ -29,7 +28,6 @@ import software.amazon.smithy.rust.codegen.core.smithy.expectRustMetadata */ class ConstrainedShapeSymbolMetadataProvider( private val base: RustSymbolProvider, - private val model: Model, private val constrainedTypes: Boolean, ) : SymbolMetadataProvider(base) { diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ConstrainedShapeSymbolProvider.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ConstrainedShapeSymbolProvider.kt index e061894f75..25b1000977 100644 --- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ConstrainedShapeSymbolProvider.kt +++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ConstrainedShapeSymbolProvider.kt @@ -6,7 +6,6 @@ package software.amazon.smithy.rust.codegen.server.smithy import software.amazon.smithy.codegen.core.Symbol -import software.amazon.smithy.model.Model import software.amazon.smithy.model.knowledge.NullableIndex import software.amazon.smithy.model.shapes.BlobShape import software.amazon.smithy.model.shapes.ByteShape @@ -62,7 +61,6 @@ import software.amazon.smithy.rust.codegen.server.smithy.traits.SyntheticStructu */ class ConstrainedShapeSymbolProvider( private val base: RustSymbolProvider, - private val model: Model, private val serviceShape: ServiceShape, private val publicConstrainedTypes: Boolean, ) : WrappingSymbolProvider(base) { @@ -88,7 +86,7 @@ class ConstrainedShapeSymbolProvider( handleRustBoxing(targetSymbol, shape), shape, nullableIndex, - base.config().nullabilityCheckMode, + base.config.nullabilityCheckMode, ) } diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ConstraintViolationSymbolProvider.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ConstraintViolationSymbolProvider.kt index b47103aa75..969b95a6f8 100644 --- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ConstraintViolationSymbolProvider.kt +++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ConstraintViolationSymbolProvider.kt @@ -6,7 +6,6 @@ package software.amazon.smithy.rust.codegen.server.smithy import software.amazon.smithy.codegen.core.Symbol -import software.amazon.smithy.model.Model import software.amazon.smithy.model.shapes.BlobShape import software.amazon.smithy.model.shapes.ByteShape import software.amazon.smithy.model.shapes.CollectionShape @@ -69,7 +68,6 @@ import software.amazon.smithy.rust.codegen.server.smithy.traits.SyntheticStructu */ class ConstraintViolationSymbolProvider( private val base: RustSymbolProvider, - private val model: Model, private val publicConstrainedTypes: Boolean, private val serviceShape: ServiceShape, ) : WrappingSymbolProvider(base) { diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/DeriveEqAndHashSymbolMetadataProvider.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/DeriveEqAndHashSymbolMetadataProvider.kt index 5438447ed5..9b54c15132 100644 --- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/DeriveEqAndHashSymbolMetadataProvider.kt +++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/DeriveEqAndHashSymbolMetadataProvider.kt @@ -5,7 +5,6 @@ package software.amazon.smithy.rust.codegen.server.smithy -import software.amazon.smithy.model.Model import software.amazon.smithy.model.shapes.BlobShape import software.amazon.smithy.model.shapes.DocumentShape import software.amazon.smithy.model.shapes.DoubleShape @@ -49,7 +48,6 @@ import software.amazon.smithy.rust.codegen.core.util.hasTrait */ class DeriveEqAndHashSymbolMetadataProvider( private val base: RustSymbolProvider, - val model: Model, ) : SymbolMetadataProvider(base) { private val walker = DirectedWalker(model) diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/PubCrateConstrainedShapeSymbolProvider.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/PubCrateConstrainedShapeSymbolProvider.kt index 59697a481e..c64182f152 100644 --- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/PubCrateConstrainedShapeSymbolProvider.kt +++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/PubCrateConstrainedShapeSymbolProvider.kt @@ -6,7 +6,6 @@ package software.amazon.smithy.rust.codegen.server.smithy import software.amazon.smithy.codegen.core.Symbol -import software.amazon.smithy.model.Model import software.amazon.smithy.model.knowledge.NullableIndex import software.amazon.smithy.model.shapes.CollectionShape import software.amazon.smithy.model.shapes.MapShape @@ -61,7 +60,6 @@ import software.amazon.smithy.rust.codegen.core.util.toSnakeCase */ class PubCrateConstrainedShapeSymbolProvider( private val base: RustSymbolProvider, - private val model: Model, private val serviceShape: ServiceShape, ) : WrappingSymbolProvider(base) { private val nullableIndex = NullableIndex.of(model) @@ -109,7 +107,7 @@ class PubCrateConstrainedShapeSymbolProvider( handleRustBoxing(targetSymbol, shape), shape, nullableIndex, - base.config().nullabilityCheckMode, + base.config.nullabilityCheckMode, ) } } diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/RustServerCodegenPlugin.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/RustServerCodegenPlugin.kt index 9bc9abeb44..7f0ac42796 100644 --- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/RustServerCodegenPlugin.kt +++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/RustServerCodegenPlugin.kt @@ -71,21 +71,21 @@ class RustServerCodegenPlugin : ServerDecoratableBuildPlugin() { ) = SymbolVisitor(model, serviceShape = serviceShape, config = rustSymbolProviderConfig) // Generate public constrained types for directly constrained shapes. - .let { if (includeConstrainedShapeProvider) ConstrainedShapeSymbolProvider(it, model, serviceShape, constrainedTypes) else it } + .let { if (includeConstrainedShapeProvider) ConstrainedShapeSymbolProvider(it, serviceShape, constrainedTypes) else it } // Generate different types for EventStream shapes (e.g. transcribe streaming) - .let { EventStreamSymbolProvider(rustSymbolProviderConfig.runtimeConfig, it, model, CodegenTarget.SERVER) } + .let { EventStreamSymbolProvider(rustSymbolProviderConfig.runtimeConfig, it, CodegenTarget.SERVER) } // Generate [ByteStream] instead of `Blob` for streaming binary shapes (e.g. S3 GetObject) - .let { StreamingShapeSymbolProvider(it, model) } + .let { StreamingShapeSymbolProvider(it) } // Add Rust attributes (like `#[derive(PartialEq)]`) to generated shapes - .let { BaseSymbolMetadataProvider(it, model, additionalAttributes = listOf()) } + .let { BaseSymbolMetadataProvider(it, additionalAttributes = listOf()) } // Constrained shapes generate newtypes that need the same derives we place on types generated from aggregate shapes. - .let { ConstrainedShapeSymbolMetadataProvider(it, model, constrainedTypes) } + .let { ConstrainedShapeSymbolMetadataProvider(it, constrainedTypes) } // Streaming shapes need different derives (e.g. they cannot derive `PartialEq`) - .let { StreamingShapeMetadataProvider(it, model) } + .let { StreamingShapeMetadataProvider(it) } // Derive `Eq` and `Hash` if possible. - .let { DeriveEqAndHashSymbolMetadataProvider(it, model) } + .let { DeriveEqAndHashSymbolMetadataProvider(it) } // Rename shapes that clash with Rust reserved words & and other SDK specific features e.g. `send()` cannot // be the name of an operation input - .let { RustReservedWordSymbolProvider(it, model) } + .let { RustReservedWordSymbolProvider(it) } } } diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerRustModule.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerRustModule.kt index 674b2eaea2..cbe23823e2 100644 --- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerRustModule.kt +++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerRustModule.kt @@ -12,6 +12,7 @@ import software.amazon.smithy.model.shapes.UnionShape import software.amazon.smithy.model.traits.ErrorTrait import software.amazon.smithy.rust.codegen.core.rustlang.RustModule import software.amazon.smithy.rust.codegen.core.smithy.ModuleProvider +import software.amazon.smithy.rust.codegen.core.smithy.ModuleProviderContext import software.amazon.smithy.rust.codegen.core.smithy.traits.SyntheticInputTrait import software.amazon.smithy.rust.codegen.core.smithy.traits.SyntheticOutputTrait import software.amazon.smithy.rust.codegen.core.util.hasTrait @@ -31,7 +32,7 @@ object ServerRustModule { } object ServerModuleProvider : ModuleProvider { - override fun moduleForShape(shape: Shape): RustModule.LeafModule = when (shape) { + override fun moduleForShape(context: ModuleProviderContext, shape: Shape): RustModule.LeafModule = when (shape) { is OperationShape -> ServerRustModule.Operation is StructureShape -> when { shape.hasTrait() -> ServerRustModule.Error @@ -42,9 +43,13 @@ object ServerModuleProvider : ModuleProvider { else -> ServerRustModule.Model } - override fun moduleForOperationError(operation: OperationShape): RustModule.LeafModule = - ServerRustModule.Error + override fun moduleForOperationError( + context: ModuleProviderContext, + operation: OperationShape, + ): RustModule.LeafModule = ServerRustModule.Error - override fun moduleForEventStreamError(eventStream: UnionShape): RustModule.LeafModule = - ServerRustModule.Error + override fun moduleForEventStreamError( + context: ModuleProviderContext, + eventStream: UnionShape, + ): RustModule.LeafModule = ServerRustModule.Error } diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerSymbolProviders.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerSymbolProviders.kt index f9fd256d3a..d4d129026f 100644 --- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerSymbolProviders.kt +++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerSymbolProviders.kt @@ -48,16 +48,14 @@ class ServerSymbolProviders private constructor( false, false, ), - model, publicConstrainedTypes, service, + publicConstrainedTypes, service, ), pubCrateConstrainedShapeSymbolProvider = PubCrateConstrainedShapeSymbolProvider( baseSymbolProvider, - model, service, ), constraintViolationSymbolProvider = ConstraintViolationSymbolProvider( baseSymbolProvider, - model, publicConstrainedTypes, service, ), diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/UnconstrainedShapeSymbolProvider.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/UnconstrainedShapeSymbolProvider.kt index 7b861c4659..711f35e462 100644 --- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/UnconstrainedShapeSymbolProvider.kt +++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/UnconstrainedShapeSymbolProvider.kt @@ -6,7 +6,6 @@ package software.amazon.smithy.rust.codegen.server.smithy import software.amazon.smithy.codegen.core.Symbol -import software.amazon.smithy.model.Model import software.amazon.smithy.model.knowledge.NullableIndex import software.amazon.smithy.model.shapes.CollectionShape import software.amazon.smithy.model.shapes.MapShape @@ -77,7 +76,6 @@ import software.amazon.smithy.rust.codegen.server.smithy.generators.serverBuilde */ class UnconstrainedShapeSymbolProvider( private val base: RustSymbolProvider, - private val model: Model, private val publicConstrainedTypes: Boolean, private val serviceShape: ServiceShape, ) : WrappingSymbolProvider(base) { @@ -168,7 +166,7 @@ class UnconstrainedShapeSymbolProvider( handleRustBoxing(targetSymbol, shape), shape, nullableIndex, - base.config().nullabilityCheckMode, + base.config.nullabilityCheckMode, ) } else { base.toSymbol(shape) diff --git a/codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ConstrainedShapeSymbolProviderTest.kt b/codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ConstrainedShapeSymbolProviderTest.kt index 39a4146351..21d7e5c48f 100644 --- a/codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ConstrainedShapeSymbolProviderTest.kt +++ b/codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ConstrainedShapeSymbolProviderTest.kt @@ -90,7 +90,7 @@ class ConstrainedShapeSymbolProviderTest { private val model = baseModelString.asSmithyModel() private val serviceShape = model.lookup("test#TestService") private val symbolProvider = serverTestSymbolProvider(model, serviceShape) - private val constrainedShapeSymbolProvider = ConstrainedShapeSymbolProvider(symbolProvider, model, serviceShape, true) + private val constrainedShapeSymbolProvider = ConstrainedShapeSymbolProvider(symbolProvider, serviceShape, true) companion object { @JvmStatic diff --git a/codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/DeriveEqAndHashSymbolMetadataProviderTest.kt b/codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/DeriveEqAndHashSymbolMetadataProviderTest.kt index 55c0c6e680..5f2dea66e2 100644 --- a/codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/DeriveEqAndHashSymbolMetadataProviderTest.kt +++ b/codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/DeriveEqAndHashSymbolMetadataProviderTest.kt @@ -171,8 +171,8 @@ internal class DeriveEqAndHashSymbolMetadataProviderTest { """.asSmithyModel(smithyVersion = "2.0") private val serviceShape = model.lookup("test#TestService") private val deriveEqAndHashSymbolMetadataProvider = serverTestSymbolProvider(model, serviceShape) - .let { BaseSymbolMetadataProvider(it, model, additionalAttributes = listOf()) } - .let { DeriveEqAndHashSymbolMetadataProvider(it, model) } + .let { BaseSymbolMetadataProvider(it, additionalAttributes = listOf()) } + .let { DeriveEqAndHashSymbolMetadataProvider(it) } companion object { @JvmStatic