From 8eae0049c3690681278ee7b3e1e6ffe7297031ab Mon Sep 17 00:00:00 2001 From: Fahad Zubair Date: Thu, 21 Nov 2024 12:23:30 +0000 Subject: [PATCH] Fix ServerAdditionalSettings to allow method calls in any order Previously, calling generateCodegenComments() before other methods would fail because it returned the parent type. Modified the class to maintain the correct type throughout method chaining. --- .../core/testutil/CodegenIntegrationTest.kt | 126 +++++++----------- .../codegen/server/smithy/ConstraintsTest.kt | 4 +- ...ionExceptionToConstrainedOperationsTest.kt | 5 +- .../CborConstraintsIntegrationTest.kt | 2 - 4 files changed, 56 insertions(+), 81 deletions(-) diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/testutil/CodegenIntegrationTest.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/testutil/CodegenIntegrationTest.kt index 817af1e09a..8a09ccc09e 100644 --- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/testutil/CodegenIntegrationTest.kt +++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/testutil/CodegenIntegrationTest.kt @@ -40,97 +40,73 @@ data class IntegrationTestParams( * model, * IntegrationTestParams( * additionalSettings = - * ServerAdditionalSettings.builder() - * .generateCodegenComments() - * .publicConstrainedTypes() + * ServerAdditionalSettings() + * .generateCodegenComments(true) + * .publicConstrainedTypes(true) * .toObjectNode() * )), * ``` */ -sealed class AdditionalSettings { - abstract fun toObjectNode(): ObjectNode - - abstract class CoreAdditionalSettings protected constructor(val settings: List) : AdditionalSettings() { - override fun toObjectNode(): ObjectNode { - val merged = - settings.map { it.toObjectNode() } - .reduce { acc, next -> acc.merge(next) } - - return ObjectNode.builder() - .withMember("codegen", merged) - .build() - } - - abstract class Builder : AdditionalSettings() { - protected val settings = mutableListOf() - - fun generateCodegenComments(debugMode: Boolean = true): Builder { - settings.add(GenerateCodegenComments(debugMode)) - return this - } - - abstract fun build(): T - - override fun toObjectNode(): ObjectNode = build().toObjectNode() +open class AdditionalSettings> { + private val codegenBuilderDelegate = + lazy { + ObjectNode.builder() } + private val codegenBuilder: ObjectNode.Builder by codegenBuilderDelegate - // Core settings that are common to both Servers and Clients should be defined here. - data class GenerateCodegenComments(val debugMode: Boolean) : AdditionalSettings() { - override fun toObjectNode(): ObjectNode = - ObjectNode.builder() - .withMember("debugMode", debugMode) - .build() + fun build(): ObjectNode { + return if (codegenBuilderDelegate.isInitialized()) { + ObjectNode.builder() + .withMember("codegen", codegenBuilder.build()) + .build() + } else { + ObjectNode.builder().build() } } -} - -class ClientAdditionalSettings private constructor(settings: List) : - AdditionalSettings.CoreAdditionalSettings(settings) { - class Builder : CoreAdditionalSettings.Builder() { - override fun build(): ClientAdditionalSettings = ClientAdditionalSettings(settings) - } - // Additional settings that are specific to client generation should be defined here. - - companion object { - fun builder() = Builder() - } + @Suppress("UNCHECKED_CAST") + open fun generateCodegenComments(debugMode: Boolean = true): T { + codegenBuilder.withMember("debugMode", debugMode) + return this as T } -class ServerAdditionalSettings private constructor(settings: List) : - AdditionalSettings.CoreAdditionalSettings(settings) { - class Builder : CoreAdditionalSettings.Builder() { - fun publicConstrainedTypes(enabled: Boolean = true): Builder { - settings.add(PublicConstrainedTypes(enabled)) - return this - } + @Suppress("UNCHECKED_CAST") + protected fun withCodegenMember( + key: String, + value: Boolean, + ): T { + codegenBuilder.withMember(key, value) + return this as T + } - fun addValidationExceptionToConstrainedOperations(enabled: Boolean = true): Builder { - settings.add(AddValidationExceptionToConstrainedOperations(enabled)) - return this - } + @Suppress("UNCHECKED_CAST") + protected fun withCodegenMember( + key: String, + value: String, + ): T { + codegenBuilder.withMember(key, value) + return this as T + } - override fun build(): ServerAdditionalSettings = ServerAdditionalSettings(settings) - } + @Suppress("UNCHECKED_CAST") + protected fun withCodegenMember( + key: String, + value: Number, + ): T { + codegenBuilder.withMember(key, value) + return this as T + } +} - private data class PublicConstrainedTypes(val enabled: Boolean) : AdditionalSettings() { - override fun toObjectNode(): ObjectNode = - ObjectNode.builder() - .withMember("publicConstrainedTypes", enabled) - .build() - } +class ServerAdditionalSettings : AdditionalSettings() { + fun publicConstrainedTypes(enabled: Boolean = true): ServerAdditionalSettings = + withCodegenMember("publicConstrainedTypes", enabled) - private data class AddValidationExceptionToConstrainedOperations(val enabled: Boolean) : AdditionalSettings() { - override fun toObjectNode(): ObjectNode = - ObjectNode.builder() - .withMember("addValidationExceptionToConstrainedOperations", enabled) - .build() - } + fun addValidationExceptionToConstrainedOperations(enabled: Boolean = true) = + withCodegenMember("addValidationExceptionToConstrainedOperations", enabled) - companion object { - fun builder() = Builder() - } - } + fun ignoreUnsupportedConstraints() = withCodegenMember("ignoreUnsupportedConstraints", true) +} /** * Run cargo test on a true, end-to-end, codegen product of a given model. diff --git a/codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ConstraintsTest.kt b/codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ConstraintsTest.kt index 36e30230c6..8087b3e08e 100644 --- a/codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ConstraintsTest.kt +++ b/codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ConstraintsTest.kt @@ -242,9 +242,9 @@ class ConstraintsTest { IntegrationTestParams( service = "test#SampleService", additionalSettings = - ServerAdditionalSettings.builder() + ServerAdditionalSettings() .publicConstrainedTypes(pubConstraints) - .toObjectNode(), + .build(), overrideTestDir = dir, ), test = test, diff --git a/codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/customizations/AddValidationExceptionToConstrainedOperationsTest.kt b/codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/customizations/AddValidationExceptionToConstrainedOperationsTest.kt index d56dd5c6f2..b15a424f34 100644 --- a/codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/customizations/AddValidationExceptionToConstrainedOperationsTest.kt +++ b/codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/customizations/AddValidationExceptionToConstrainedOperationsTest.kt @@ -76,9 +76,10 @@ internal class AddValidationExceptionToConstrainedOperationsTest { testModelWithValidationExceptionImported, IntegrationTestParams( additionalSettings = - ServerAdditionalSettings.builder() + ServerAdditionalSettings() + .generateCodegenComments(true) .addValidationExceptionToConstrainedOperations() - .toObjectNode(), + .build(), ), ) } diff --git a/codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/protocols/serialize/CborConstraintsIntegrationTest.kt b/codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/protocols/serialize/CborConstraintsIntegrationTest.kt index 0a80a125d6..3c18d765a8 100644 --- a/codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/protocols/serialize/CborConstraintsIntegrationTest.kt +++ b/codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/protocols/serialize/CborConstraintsIntegrationTest.kt @@ -6,7 +6,6 @@ package software.amazon.smithy.rust.codegen.server.smithy.protocols.serialize import org.junit.jupiter.api.Test import software.amazon.smithy.rust.codegen.core.testutil.IntegrationTestParams -import software.amazon.smithy.rust.codegen.core.testutil.ServerAdditionalSettings import software.amazon.smithy.rust.codegen.server.smithy.ModelProtocol import software.amazon.smithy.rust.codegen.server.smithy.loadSmithyConstraintsModelForProtocol import software.amazon.smithy.rust.codegen.server.smithy.testutil.serverIntegrationTest @@ -20,7 +19,6 @@ class CborConstraintsIntegrationTest { model, IntegrationTestParams( service = serviceShape.toString(), - additionalSettings = ServerAdditionalSettings.builder().generateCodegenComments().toObjectNode(), ), ) { _, _ -> }