diff --git a/codegen/smithy-go-codegen-test/build.gradle.kts b/codegen/smithy-go-codegen-test/build.gradle.kts index 5b8a4f29b..319499c67 100644 --- a/codegen/smithy-go-codegen-test/build.gradle.kts +++ b/codegen/smithy-go-codegen-test/build.gradle.kts @@ -43,5 +43,6 @@ repositories { dependencies { implementation("software.amazon.smithy:smithy-protocol-test-traits:$smithyVersion") + implementation("software.amazon.smithy:smithy-aws-traits:$smithyVersion") implementation(project(":smithy-go-codegen")) } diff --git a/codegen/smithy-go-codegen-test/model/main.smithy b/codegen/smithy-go-codegen-test/model/main.smithy index d41e76f8b..5bfeb1c7a 100644 --- a/codegen/smithy-go-codegen-test/model/main.smithy +++ b/codegen/smithy-go-codegen-test/model/main.smithy @@ -8,6 +8,7 @@ use smithy.waiters#waitable /// Provides weather forecasts. @httpBearerAuth @fakeProtocol +@aws.protocols#awsJson1_0 @paginated(inputToken: "nextToken", outputToken: "nextToken", pageSize: "pageSize") service Weather { version: "2006-03-01", diff --git a/codegen/smithy-go-codegen-test/smithy-build.json b/codegen/smithy-go-codegen-test/smithy-build.json index b495c9292..9f7bd5308 100644 --- a/codegen/smithy-go-codegen-test/smithy-build.json +++ b/codegen/smithy-go-codegen-test/smithy-build.json @@ -7,6 +7,13 @@ "moduleVersion": "0.0.1", "generateGoMod": true, "goDirective": "1.18" + }, + "go-server-codegen": { + "service": "example.weather#Weather", + "module": "github.com/aws/smithy-go/internal/tests/service/weather", + "moduleVersion": "0.0.1", + "generateGoMod": true, + "goDirective": "1.18" } } } diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/CodegenVisitor.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/CodegenVisitor.java index ee26839c4..2c849c75d 100644 --- a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/CodegenVisitor.java +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/CodegenVisitor.java @@ -32,6 +32,7 @@ import software.amazon.smithy.codegen.core.Symbol; import software.amazon.smithy.codegen.core.SymbolDependency; import software.amazon.smithy.codegen.core.SymbolProvider; +import software.amazon.smithy.go.codegen.GoSettings.ArtifactType; import software.amazon.smithy.go.codegen.integration.GoIntegration; import software.amazon.smithy.go.codegen.integration.ProtocolGenerator; import software.amazon.smithy.go.codegen.integration.RuntimeClientPlugin; @@ -51,10 +52,12 @@ import software.amazon.smithy.model.traits.EnumTrait; import software.amazon.smithy.model.transform.ModelTransformer; import software.amazon.smithy.utils.OptionalUtils; +import software.amazon.smithy.utils.SmithyInternalApi; /** * Orchestrates Go client generation. */ +@SmithyInternalApi final class CodegenVisitor extends ShapeVisitor.Default { private static final Logger LOGGER = Logger.getLogger(CodegenVisitor.class.getName()); @@ -79,8 +82,10 @@ final class CodegenVisitor extends ShapeVisitor.Default { LOGGER.info("Attempting to discover GoIntegration from the classpath..."); ServiceLoader.load(GoIntegration.class, loader) .forEach(integration -> { - LOGGER.info(() -> "Adding GoIntegration: " + integration.getClass().getName()); - integrations.add(integration); + if (integration.getArtifactType().equals(ArtifactType.CLIENT)) { + LOGGER.info(() -> "Adding GoIntegration: " + integration.getClass().getName()); + integrations.add(integration); + } }); integrations.sort(Comparator.comparingInt(GoIntegration::getOrder)); diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/EnumGenerator.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/EnumGenerator.java index e689d0aac..496ffffce 100644 --- a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/EnumGenerator.java +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/EnumGenerator.java @@ -24,19 +24,21 @@ import software.amazon.smithy.model.shapes.StringShape; import software.amazon.smithy.model.traits.EnumDefinition; import software.amazon.smithy.model.traits.EnumTrait; +import software.amazon.smithy.utils.SmithyInternalApi; import software.amazon.smithy.utils.StringUtils; /** * Renders enums and their constants. */ -final class EnumGenerator implements Runnable { +@SmithyInternalApi +public final class EnumGenerator implements Runnable { private static final Logger LOGGER = Logger.getLogger(EnumGenerator.class.getName()); private final SymbolProvider symbolProvider; private final GoWriter writer; private final StringShape shape; - EnumGenerator(SymbolProvider symbolProvider, GoWriter writer, StringShape shape) { + public EnumGenerator(SymbolProvider symbolProvider, GoWriter writer, StringShape shape) { this.symbolProvider = symbolProvider; this.writer = writer; this.shape = shape; diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoDelegator.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoDelegator.java index 10494d411..15d22ac19 100644 --- a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoDelegator.java +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoDelegator.java @@ -21,15 +21,17 @@ import software.amazon.smithy.codegen.core.SymbolProvider; import software.amazon.smithy.codegen.core.SymbolReference; import software.amazon.smithy.model.shapes.Shape; +import software.amazon.smithy.utils.SmithyInternalApi; /** * Manages writers for Go files.Based off of GoWriterDelegator adding support * for getting shape specific GoWriters. */ +@SmithyInternalApi public final class GoDelegator extends GoWriterDelegator { private final SymbolProvider symbolProvider; - GoDelegator(FileManifest fileManifest, SymbolProvider symbolProvider) { + public GoDelegator(FileManifest fileManifest, SymbolProvider symbolProvider) { super(fileManifest); this.symbolProvider = symbolProvider; diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoModGenerator.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoModGenerator.java index 93208adf5..a4b6f81e2 100644 --- a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoModGenerator.java +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoModGenerator.java @@ -22,19 +22,21 @@ import java.util.logging.Logger; import software.amazon.smithy.build.FileManifest; import software.amazon.smithy.codegen.core.CodegenException; +import software.amazon.smithy.utils.SmithyInternalApi; /** * Generates a go.mod file for the project. * *

See here for more information on the format: https://github.com/golang/go/wiki/Modules#gomod */ -final class GoModGenerator { +@SmithyInternalApi +public final class GoModGenerator { private static final Logger LOGGER = Logger.getLogger(GoModGenerator.class.getName()); private GoModGenerator() {} - static void writeGoMod( + public static void writeGoMod( GoSettings settings, FileManifest manifest, GoModuleInfo goModuleInfo diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoSettings.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoSettings.java index c9f44ac48..0aafb2752 100644 --- a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoSettings.java +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoSettings.java @@ -25,10 +25,12 @@ 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.utils.SmithyInternalApi; /** * Settings used by {@link GoCodegenPlugin}. */ +@SmithyInternalApi public final class GoSettings { private static final String SERVICE = "service"; @@ -45,6 +47,13 @@ public final class GoSettings { private Boolean generateGoMod = false; private String goDirective = GoModuleInfo.DEFAULT_GO_DIRECTIVE; private ShapeId protocol; + private ArtifactType artifactType; + + @SmithyInternalApi + public enum ArtifactType { + CLIENT, + SERVER; + } /** * Create a settings object from a configuration object node. @@ -53,10 +62,15 @@ public final class GoSettings { * @return Returns the extracted settings. */ public static GoSettings from(ObjectNode config) { + return from(config, ArtifactType.CLIENT); + } + + @SmithyInternalApi + public static GoSettings from(ObjectNode config, ArtifactType artifactType) { GoSettings settings = new GoSettings(); config.warnIfAdditionalProperties( Arrays.asList(SERVICE, MODULE_NAME, MODULE_DESCRIPTION, MODULE_VERSION, GENERATE_GO_MOD, GO_DIRECTIVE)); - + settings.setArtifactType(artifactType); settings.setService(config.expectStringMember(SERVICE).expectShapeId()); settings.setModuleName(config.expectStringMember(MODULE_NAME).getValue()); settings.setModuleDescription(config.getStringMemberOrDefault( @@ -241,4 +255,14 @@ public ShapeId resolveServiceProtocol( public void setProtocol(ShapeId protocol) { this.protocol = Objects.requireNonNull(protocol); } + + @SmithyInternalApi + public ArtifactType getArtifactType() { + return artifactType; + } + + @SmithyInternalApi + public void setArtifactType(ArtifactType artifactType) { + this.artifactType = artifactType; + } } diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoWriter.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoWriter.java index e5cd6b83f..fec60f42b 100644 --- a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoWriter.java +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoWriter.java @@ -47,6 +47,7 @@ import software.amazon.smithy.model.traits.StringTrait; import software.amazon.smithy.utils.AbstractCodeWriter; import software.amazon.smithy.utils.ListUtils; +import software.amazon.smithy.utils.SmithyInternalApi; import software.amazon.smithy.utils.StringUtils; /** @@ -56,6 +57,7 @@ * *

Use the {@code $P} formatter to refer to {@link Symbol}s using pointers where appropriate. */ +@SmithyInternalApi public final class GoWriter extends AbstractCodeWriter { private static final Logger LOGGER = Logger.getLogger(GoWriter.class.getName()); @@ -773,7 +775,8 @@ public GoWriter writeRawPackageDocs(String docs) { * @param shape Shape to write the documentation of. * @return Returns true if docs were written. */ - boolean writeShapeDocs(Shape shape) { + @SmithyInternalApi + public boolean writeShapeDocs(Shape shape) { return shape.getTrait(DocumentationTrait.class) .map(DocumentationTrait::getValue) .map(docs -> { @@ -788,7 +791,7 @@ boolean writeShapeDocs(Shape shape) { * @param shape Shape to write the documentation of. * @return Returns true if docs were written. */ - boolean writePackageShapeDocs(Shape shape) { + public boolean writePackageShapeDocs(Shape shape) { return shape.getTrait(DocumentationTrait.class) .map(DocumentationTrait::getValue) .map(docs -> { diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/IntEnumGenerator.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/IntEnumGenerator.java index cf4059183..e211ba74a 100644 --- a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/IntEnumGenerator.java +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/IntEnumGenerator.java @@ -26,19 +26,21 @@ import software.amazon.smithy.model.shapes.MemberShape; import software.amazon.smithy.model.traits.DocumentationTrait; import software.amazon.smithy.model.traits.EnumValueTrait; +import software.amazon.smithy.utils.SmithyInternalApi; import software.amazon.smithy.utils.StringUtils; /** * Renders intEnums and their constants. */ -final class IntEnumGenerator implements Runnable { +@SmithyInternalApi +public final class IntEnumGenerator implements Runnable { private static final Logger LOGGER = Logger.getLogger(IntEnumGenerator.class.getName()); private final SymbolProvider symbolProvider; private final GoWriter writer; private final IntEnumShape shape; - IntEnumGenerator(SymbolProvider symbolProvider, GoWriter writer, IntEnumShape shape) { + public IntEnumGenerator(SymbolProvider symbolProvider, GoWriter writer, IntEnumShape shape) { this.symbolProvider = symbolProvider; this.writer = writer; this.shape = shape; diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/ManifestWriter.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/ManifestWriter.java index 0cbeb50a0..38c09e2f3 100644 --- a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/ManifestWriter.java +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/ManifestWriter.java @@ -34,11 +34,13 @@ import software.amazon.smithy.model.node.StringNode; import software.amazon.smithy.model.traits.UnstableTrait; import software.amazon.smithy.utils.SmithyBuilder; +import software.amazon.smithy.utils.SmithyInternalApi; /** * Generates a manifest description of the generated code, minimum go version, * and minimum dependencies required. */ +@SmithyInternalApi public final class ManifestWriter { private static final Logger LOGGER = Logger.getLogger(ManifestWriter.class.getName()); diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/StructureGenerator.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/StructureGenerator.java index e8c838772..cb2a12ca2 100644 --- a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/StructureGenerator.java +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/StructureGenerator.java @@ -28,11 +28,13 @@ import software.amazon.smithy.model.traits.StreamingTrait; import software.amazon.smithy.utils.MapUtils; import software.amazon.smithy.utils.SetUtils; +import software.amazon.smithy.utils.SmithyInternalApi; /** * Renders structures. */ -final class StructureGenerator implements Runnable { +@SmithyInternalApi +public final class StructureGenerator implements Runnable { private static final Map STANDARD_ERROR_MEMBERS = MapUtils.of( "ErrorCode", "string", "ErrorMessage", "string", @@ -48,7 +50,7 @@ final class StructureGenerator implements Runnable { private final ServiceShape service; private final ProtocolGenerator protocolGenerator; - StructureGenerator( + public StructureGenerator( Model model, SymbolProvider symbolProvider, GoWriter writer, diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/SymbolVisitor.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/SymbolVisitor.java index e60fd0267..342dd473b 100644 --- a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/SymbolVisitor.java +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/SymbolVisitor.java @@ -62,6 +62,7 @@ import software.amazon.smithy.model.traits.EnumTrait; import software.amazon.smithy.model.traits.ErrorTrait; import software.amazon.smithy.model.traits.StreamingTrait; +import software.amazon.smithy.utils.SmithyInternalApi; import software.amazon.smithy.utils.StringUtils; /** @@ -70,7 +71,8 @@ *

Reserved words for Go are automatically escaped so that they are * suffixed with "_". See "reserved-words.txt" for the list of words. */ -final class SymbolVisitor implements SymbolProvider, ShapeVisitor { +@SmithyInternalApi +public final class SymbolVisitor implements SymbolProvider, ShapeVisitor { private static final Logger LOGGER = Logger.getLogger(SymbolVisitor.class.getName()); private final Model model; @@ -82,7 +84,7 @@ final class SymbolVisitor implements SymbolProvider, ShapeVisitor { private final GoPointableIndex pointableIndex; private final GoSettings settings; - SymbolVisitor(Model model, GoSettings settings) { + public SymbolVisitor(Model model, GoSettings settings) { this.model = model; this.settings = settings; this.rootModuleName = settings.getModuleName(); diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/UnionGenerator.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/UnionGenerator.java index 0e4b87227..53aa06264 100644 --- a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/UnionGenerator.java +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/UnionGenerator.java @@ -29,10 +29,12 @@ import software.amazon.smithy.model.shapes.UnionShape; import software.amazon.smithy.model.traits.ErrorTrait; import software.amazon.smithy.model.traits.StreamingTrait; +import software.amazon.smithy.utils.SmithyInternalApi; /** * Renders unions and type aliases for all their members. */ +@SmithyInternalApi public class UnionGenerator { public static final String UNKNOWN_MEMBER_NAME = "UnknownUnionMember"; @@ -41,7 +43,7 @@ public class UnionGenerator { private final UnionShape shape; private final boolean isEventStream; - UnionGenerator(Model model, SymbolProvider symbolProvider, UnionShape shape) { + public UnionGenerator(Model model, SymbolProvider symbolProvider, UnionShape shape) { this.model = model; this.symbolProvider = symbolProvider; this.shape = shape; diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/integration/GoIntegration.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/integration/GoIntegration.java index 077c43ff9..a53a08e93 100644 --- a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/integration/GoIntegration.java +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/integration/GoIntegration.java @@ -21,17 +21,20 @@ import software.amazon.smithy.codegen.core.SymbolProvider; import software.amazon.smithy.go.codegen.GoDelegator; import software.amazon.smithy.go.codegen.GoSettings; +import software.amazon.smithy.go.codegen.GoSettings.ArtifactType; import software.amazon.smithy.go.codegen.GoWriter; import software.amazon.smithy.go.codegen.TriConsumer; import software.amazon.smithy.model.Model; import software.amazon.smithy.model.shapes.ServiceShape; import software.amazon.smithy.model.shapes.Shape; +import software.amazon.smithy.utils.SmithyUnstableApi; /** * Java SPI for customizing Go code generation, registering * new protocol code generators, renaming shapes, modifying the model, * adding custom code, etc. */ +@SmithyUnstableApi public interface GoIntegration { /** * Gets the sort order of the customization from -128 to 127. @@ -49,6 +52,10 @@ default byte getOrder() { return 0; } + default ArtifactType getArtifactType() { + return ArtifactType.CLIENT; + } + /** * Preprocess the model before code generation. * diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/GoServerCodegenPlugin.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/GoServerCodegenPlugin.java new file mode 100644 index 000000000..99537baef --- /dev/null +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/GoServerCodegenPlugin.java @@ -0,0 +1,73 @@ +/* + * Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.go.codegen.service; + +import java.util.logging.Logger; +import software.amazon.smithy.build.PluginContext; +import software.amazon.smithy.build.SmithyBuildPlugin; +import software.amazon.smithy.codegen.core.SymbolProvider; +import software.amazon.smithy.go.codegen.GoSettings; +import software.amazon.smithy.go.codegen.GoSettings.ArtifactType; +import software.amazon.smithy.go.codegen.SymbolVisitor; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.utils.SmithyInternalApi; + +/** + * Plugin to trigger Go code generation. + */ +@SmithyInternalApi +public final class GoServerCodegenPlugin implements SmithyBuildPlugin { + private static final Logger LOGGER = Logger.getLogger(GoServerCodegenPlugin.class.getName()); + + @Override + public String getName() { + return "go-server-codegen"; + } + + @Override + public void execute(PluginContext context) { + String onlyBuild = System.getenv("SMITHY_GO_BUILD_API"); + if (onlyBuild != null && !onlyBuild.isEmpty()) { + String targetServiceId = + GoSettings.from(context.getSettings(), ArtifactType.SERVER).getService().toString(); + + boolean found = false; + for (String includeServiceId : onlyBuild.split(",")) { + if (targetServiceId.startsWith(includeServiceId)) { + found = true; + break; + } + } + if (!found) { + LOGGER.info("skipping " + targetServiceId); + return; + } + } + + new ServerCodegenVisitor(context).execute(); + } + + /** + * Creates a Go symbol provider. + * + * @param model The model to generate symbols for. + * @param settings The Gosettings to use to create symbol provider + * @return Returns the created provider. + */ + public static SymbolProvider createSymbolProvider(Model model, GoSettings settings) { + return new SymbolVisitor(model, settings); + } +} diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/GoServerIntegration.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/GoServerIntegration.java new file mode 100644 index 000000000..aac23861a --- /dev/null +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/GoServerIntegration.java @@ -0,0 +1,41 @@ +/* + * Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.go.codegen.service; + +import java.util.Collections; +import java.util.List; +import software.amazon.smithy.codegen.core.SymbolProvider; +import software.amazon.smithy.go.codegen.GoSettings.ArtifactType; +import software.amazon.smithy.go.codegen.integration.GoIntegration; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.utils.SmithyInternalApi; + +@SmithyInternalApi +public interface GoServerIntegration extends GoIntegration { + @Override + default ArtifactType getArtifactType() { + return ArtifactType.SERVER; + } + + default List getServerProtocolGenerators( + Model model, + ServiceShape service, + SymbolProvider symbolProvider + ) { + return Collections.emptyList(); + } +} diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/ServerCodegenVisitor.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/ServerCodegenVisitor.java new file mode 100644 index 000000000..450d45bc2 --- /dev/null +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/ServerCodegenVisitor.java @@ -0,0 +1,329 @@ +/* + * Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.go.codegen.service; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.ServiceLoader; +import java.util.Set; +import java.util.TreeSet; +import java.util.logging.Logger; +import java.util.stream.Collectors; +import software.amazon.smithy.build.FileManifest; +import software.amazon.smithy.build.PluginContext; +import software.amazon.smithy.codegen.core.Symbol; +import software.amazon.smithy.codegen.core.SymbolDependency; +import software.amazon.smithy.codegen.core.SymbolProvider; +import software.amazon.smithy.go.codegen.AddOperationShapes; +import software.amazon.smithy.go.codegen.ApplicationProtocol; +import software.amazon.smithy.go.codegen.CodegenUtils; +import software.amazon.smithy.go.codegen.EnumGenerator; +import software.amazon.smithy.go.codegen.EventStreamGenerator; +import software.amazon.smithy.go.codegen.GoDelegator; +import software.amazon.smithy.go.codegen.GoModGenerator; +import software.amazon.smithy.go.codegen.GoModuleInfo; +import software.amazon.smithy.go.codegen.GoSettings; +import software.amazon.smithy.go.codegen.GoSettings.ArtifactType; +import software.amazon.smithy.go.codegen.GoWriter; +import software.amazon.smithy.go.codegen.IntEnumGenerator; +import software.amazon.smithy.go.codegen.ManifestWriter; +import software.amazon.smithy.go.codegen.ProtocolDocumentGenerator; +import software.amazon.smithy.go.codegen.StructureGenerator; +import software.amazon.smithy.go.codegen.UnionGenerator; +import software.amazon.smithy.go.codegen.integration.GoIntegration; +import software.amazon.smithy.go.codegen.integration.RuntimeClientPlugin; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.knowledge.ServiceIndex; +import software.amazon.smithy.model.knowledge.TopDownIndex; +import software.amazon.smithy.model.neighbor.Walker; +import software.amazon.smithy.model.shapes.IntEnumShape; +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.ShapeId; +import software.amazon.smithy.model.shapes.ShapeVisitor; +import software.amazon.smithy.model.shapes.StringShape; +import software.amazon.smithy.model.shapes.StructureShape; +import software.amazon.smithy.model.shapes.UnionShape; +import software.amazon.smithy.model.traits.EnumTrait; +import software.amazon.smithy.model.transform.ModelTransformer; +import software.amazon.smithy.utils.OptionalUtils; +import software.amazon.smithy.utils.SmithyInternalApi; + +/** + * Orchestrates Go client generation. + */ +@SmithyInternalApi +final class ServerCodegenVisitor extends ShapeVisitor.Default { + + private static final Logger LOGGER = Logger.getLogger(ServerCodegenVisitor.class.getName()); + + private final GoSettings settings; + private final Model model; + private final Model modelWithoutTraitShapes; + private final ServiceShape service; + private final FileManifest fileManifest; + private final SymbolProvider symbolProvider; + private final GoDelegator writers; + private final List integrations = new ArrayList<>(); + private final ServerProtocolGenerator protocolGenerator; + private final ApplicationProtocol applicationProtocol; + private final List runtimePlugins = new ArrayList<>(); + private final ProtocolDocumentGenerator protocolDocumentGenerator; + private final EventStreamGenerator eventStreamGenerator; + + ServerCodegenVisitor(PluginContext context) { + // Load all integrations. + ClassLoader loader = context.getPluginClassLoader().orElse(getClass().getClassLoader()); + LOGGER.info("Attempting to discover GoServerIntegration from the classpath..."); + ServiceLoader.load(GoIntegration.class, loader) + .forEach(integration -> { + if (integration.getArtifactType().equals(ArtifactType.SERVER)) { + LOGGER.info(() -> "Adding GoIntegration: " + integration.getClass().getName()); + integrations.add((GoServerIntegration) integration); + } + }); + integrations.sort(Comparator.comparingInt(GoServerIntegration::getOrder)); + + settings = GoSettings.from(context.getSettings()); + fileManifest = context.getFileManifest(); + + Model resolvedModel = context.getModel(); + + var modelTransformer = ModelTransformer.create(); + + /* + * smithy 1.23.0 added support for mixins. This transform flattens and applies + * the mixins + * and remove them from the model + */ + resolvedModel = modelTransformer.flattenAndRemoveMixins(resolvedModel); + + // Add unique operation input/output shapes + resolvedModel = AddOperationShapes.execute(resolvedModel, settings.getService()); + + /* + * smithy 1.12.0 added support for binding common errors to the service shape + * this transform copies these common errors to the operations + */ + resolvedModel = modelTransformer.copyServiceErrorsToOperations(resolvedModel, + settings.getService(resolvedModel)); + + LOGGER.info(() -> "Preprocessing smithy model"); + for (GoServerIntegration goIntegration : integrations) { + resolvedModel = goIntegration.preprocessModel(resolvedModel, settings); + } + + model = resolvedModel; + + // process final model + integrations.forEach(integration -> { + integration.processFinalizedModel(settings, model); + }); + + // fetch runtime plugins + integrations.forEach(integration -> { + integration.getClientPlugins().forEach(runtimePlugin -> { + LOGGER.info(() -> "Adding Go runtime plugin: " + runtimePlugin); + runtimePlugins.add(runtimePlugin); + }); + }); + + modelWithoutTraitShapes = modelTransformer.getModelWithoutTraitShapes(model); + + service = settings.getService(model); + LOGGER.info(() -> "Generating Go server for service " + service.getId()); + + SymbolProvider resolvedProvider = GoServerCodegenPlugin.createSymbolProvider(model, settings); + for (GoServerIntegration integration : integrations) { + resolvedProvider = integration.decorateSymbolProvider(settings, model, resolvedProvider); + } + symbolProvider = resolvedProvider; + + protocolGenerator = resolveProtocolGenerator(integrations, model, service, settings, symbolProvider); + applicationProtocol = protocolGenerator.getApplicationProtocol(); + + writers = new GoDelegator(fileManifest, symbolProvider); + + // TODO(SSDK): do we need this? + protocolDocumentGenerator = new ProtocolDocumentGenerator(settings, model, writers); + + // TODO(SSDK): do we need this? + this.eventStreamGenerator = new EventStreamGenerator(settings, model, writers, symbolProvider, service); + } + + private static ServerProtocolGenerator resolveProtocolGenerator( + Collection integrations, + Model model, + ServiceShape service, + GoSettings settings, + SymbolProvider symbolProvider + ) { + // Collect all the supported protocol generators. + Map generators = new HashMap<>(); + for (GoServerIntegration integration : integrations) { + List protocolGenerators = + integration.getServerProtocolGenerators(model, service, symbolProvider); + for (ServerProtocolGenerator generator : protocolGenerators) { + generators.put(generator.getProtocol(), generator); + } + } + + ServiceIndex serviceIndex = ServiceIndex.of(model); + + ShapeId protocolTrait = settings.resolveServiceProtocol(serviceIndex, service, generators.keySet()); + settings.setProtocol(protocolTrait); + return generators.get(protocolTrait); + } + + void execute() { + // Generate models that are connected to the service being generated. + LOGGER.fine("Walking shapes from " + service.getId() + " to find shapes to generate"); + Set serviceShapes = new TreeSet<>(new Walker(modelWithoutTraitShapes).walkShapes(service)); + + for (Shape shape : serviceShapes) { + shape.accept(this); + } + + // Generate any required types and functions need to support protocol documents. + protocolDocumentGenerator.generateDocumentSupport(); + + // Generate a struct to handle unknown tags in unions + List unions = serviceShapes.stream() + .map(Shape::asUnionShape) + .flatMap(OptionalUtils::stream) + .collect(Collectors.toList()); + if (!unions.isEmpty()) { + writers.useShapeWriter(unions.get(0), writer -> { + UnionGenerator.generateUnknownUnion(writer, unions, symbolProvider); + }); + } + + for (GoServerIntegration integration : integrations) { + integration.writeAdditionalFiles(settings, model, symbolProvider, writers::useFileWriter); + integration.writeAdditionalFiles(settings, model, symbolProvider, writers); + } + + eventStreamGenerator.generateEventStreamInterfaces(); + TopDownIndex.of(model).getContainedOperations(service) + .forEach(eventStreamGenerator::generateOperationEventStreamStructure); + + if (protocolGenerator != null) { + LOGGER.info("Generating serde for protocol " + protocolGenerator.getProtocol() + " on " + service.getId()); + + writers.useFileWriter("feat_svcgen.go", settings.getModuleName(), GoWriter.ChainWritable.of( + protocolGenerator.generateSource(), + new ServiceInterface(model, service, symbolProvider), + new NoopServiceStruct(model, service, symbolProvider), + new NotImplementedError(), + new ServiceStruct(protocolGenerator) + ).compose()); + } + + LOGGER.fine("Flushing go writers"); + List dependencies = writers.getDependencies(); + writers.flushWriters(); + + GoModuleInfo goModuleInfo = new GoModuleInfo.Builder() + .goDirective(settings.getGoDirective()) + .dependencies(dependencies) + .build(); + + GoModGenerator.writeGoMod(settings, fileManifest, goModuleInfo); + + LOGGER.fine("Generating build manifest file"); + ManifestWriter.writeManifest(settings, model, fileManifest, goModuleInfo); + } + + @Override + protected Void getDefault(Shape shape) { + return null; + } + + @Override + public Void structureShape(StructureShape shape) { + if (shape.getId().getNamespace().equals(CodegenUtils.getSyntheticTypeNamespace())) { + return null; + } + Symbol symbol = symbolProvider.toSymbol(shape); + writers.useShapeWriter(shape, writer -> new StructureGenerator( + model, symbolProvider, writer, service, shape, symbol, null).run()); + return null; + } + + @Override + public Void stringShape(StringShape shape) { + if (shape.hasTrait(EnumTrait.class)) { + writers.useShapeWriter(shape, writer -> new EnumGenerator(symbolProvider, writer, shape).run()); + } + return null; + } + + @Override + public Void unionShape(UnionShape shape) { + UnionGenerator generator = new UnionGenerator(model, symbolProvider, shape); + writers.useShapeWriter(shape, generator::generateUnion); + writers.useShapeExportedTestWriter(shape, generator::generateUnionExamples); + return null; + } + + @Override + public Void serviceShape(ServiceShape shape) { + if (!Objects.equals(service, shape)) { + LOGGER.fine(() -> "Skipping `" + shape.getId() + "` because it is not `" + service.getId() + "`"); + return null; + } + + // Write API server's package doc for the service. + writers.useFileWriter("doc.go", settings.getModuleName(), (writer) -> { + writer.writePackageDocs(String.format( + "Package %s provides the API server, operations, and parameter types for %s.", + CodegenUtils.getDefaultPackageImportName(settings.getModuleName()), + CodegenUtils.getServiceTitle(shape, "the API"))); + writer.writePackageDocs(""); + writer.writePackageShapeDocs(shape); + }); + + // Write API client type and utilities. + writers.useShapeWriter(shape, serviceWriter -> { + // TODO(SSDK): generate server stuff, like Client ServiceGenerator + + TopDownIndex topDownIndex = TopDownIndex.of(model); + Set containedOperations = new TreeSet<>(topDownIndex.getContainedOperations(service)); + for (OperationShape operation : containedOperations) { + new ServerOperationGenerator( + model, + symbolProvider, + serviceWriter, + service, + operation + ).run(); + } + }); + return null; + } + + @Override + public Void intEnumShape(IntEnumShape shape) { + writers.useShapeWriter(shape, writer -> new IntEnumGenerator(symbolProvider, writer, shape).run()); + return null; + } +} diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/ServerOperationGenerator.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/ServerOperationGenerator.java new file mode 100644 index 000000000..12beebec3 --- /dev/null +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/ServerOperationGenerator.java @@ -0,0 +1,135 @@ +/* + * Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.go.codegen.service; + +import java.util.stream.Stream; +import software.amazon.smithy.codegen.core.CodegenException; +import software.amazon.smithy.codegen.core.Symbol; +import software.amazon.smithy.codegen.core.SymbolProvider; +import software.amazon.smithy.go.codegen.EventStreamGenerator; +import software.amazon.smithy.go.codegen.GoWriter; +import software.amazon.smithy.go.codegen.SmithyGoDependency; +import software.amazon.smithy.go.codegen.StructureGenerator; +import software.amazon.smithy.go.codegen.SymbolUtils; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.knowledge.OperationIndex; +import software.amazon.smithy.model.shapes.OperationShape; +import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.model.shapes.StructureShape; +import software.amazon.smithy.model.traits.DeprecatedTrait; +import software.amazon.smithy.model.traits.StreamingTrait; +import software.amazon.smithy.utils.SmithyInternalApi; + +/** + * Generates a client operation and associated custom shapes. + */ +@SmithyInternalApi +public final class ServerOperationGenerator implements Runnable { + + private final Model model; + private final SymbolProvider symbolProvider; + private final GoWriter writer; + private final ServiceShape service; + private final OperationShape operation; + + public ServerOperationGenerator( + Model model, + SymbolProvider symbolProvider, + GoWriter writer, + ServiceShape service, + OperationShape operation + ) { + this.model = model; + this.symbolProvider = symbolProvider; + this.writer = writer; + this.service = service; + this.operation = operation; + } + + @Override + public void run() { + OperationIndex operationIndex = OperationIndex.of(model); + + if (!operationIndex.getInput(operation).isPresent()) { + // Theoretically this shouldn't ever get hit since we automatically insert synthetic inputs / outputs. + throw new CodegenException( + "Operations are required to have input shapes in order to allow for future evolution."); + } + StructureShape inputShape = operationIndex.getInput(operation).get(); + Symbol inputSymbol = symbolProvider.toSymbol(inputShape); + + if (!operationIndex.getOutput(operation).isPresent()) { + throw new CodegenException( + "Operations are required to have output shapes in order to allow for future evolution."); + } + StructureShape outputShape = operationIndex.getOutput(operation).get(); + Symbol outputSymbol = symbolProvider.toSymbol(outputShape); + + // Generate operation method + final boolean hasDocs = writer.writeShapeDocs(operation); + operation.getTrait(DeprecatedTrait.class) + .ifPresent(trait -> { + if (hasDocs) { + writer.writeDocs(""); + } + final String defaultMessage = "This operation has been deprecated."; + writer.writeDocs("Deprecated: " + trait.getMessage().map(s -> { + if (s.length() == 0) { + return defaultMessage; + } + return s; + }).orElse(defaultMessage)); + }); + // Write out the input and output structures. These are written out here to prevent naming conflicts with other + // shapes in the model. + new StructureGenerator(model, symbolProvider, writer, service, inputShape, inputSymbol, null) + .renderStructure(() -> { }, true); + + // The output structure gets a metadata member added. + Symbol metadataSymbol = SymbolUtils.createValueSymbolBuilder("Metadata", SmithyGoDependency.SMITHY_MIDDLEWARE) + .build(); + + boolean hasEventStream = Stream.concat(inputShape.members().stream(), + outputShape.members().stream()) + .anyMatch(memberShape -> StreamingTrait.isEventStream(model, memberShape)); + + new StructureGenerator(model, symbolProvider, writer, service, outputShape, outputSymbol, null) + .renderStructure(() -> { + if (outputShape.getMemberNames().size() != 0) { + writer.write(""); + } + + if (hasEventStream) { + writer.write("eventStream $P", + EventStreamGenerator.getEventStreamOperationStructureSymbol(service, operation)) + .write(""); + } + + writer.writeDocs("Metadata pertaining to the operation's result."); + writer.write("ResultMetadata $T", metadataSymbol); + }); + + if (hasEventStream) { + writer.write(""" + // GetStream returns the type to interact with the event stream. + func (o $P) GetStream() $P { + return o.eventStream + } + """, outputSymbol, EventStreamGenerator.getEventStreamOperationStructureSymbol( + service, operation)); + } + } +} diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/ProtocolGenerator.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/ServerProtocolGenerator.java similarity index 83% rename from codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/ProtocolGenerator.java rename to codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/ServerProtocolGenerator.java index 02979bde6..e3136fd64 100644 --- a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/ProtocolGenerator.java +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/ServerProtocolGenerator.java @@ -15,9 +15,19 @@ package software.amazon.smithy.go.codegen.service; +import software.amazon.smithy.go.codegen.ApplicationProtocol; import software.amazon.smithy.go.codegen.GoWriter; +import software.amazon.smithy.model.shapes.ShapeId; +import software.amazon.smithy.utils.SmithyInternalApi; -public interface ProtocolGenerator { +@SmithyInternalApi +public interface ServerProtocolGenerator { + // Smithy + ApplicationProtocol getApplicationProtocol(); + + ShapeId getProtocol(); + + // Go /** * Generate all supporting source code required by this protocol. */ diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/ServiceStruct.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/ServiceStruct.java index 9989794d7..020f37c4b 100644 --- a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/ServiceStruct.java +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/ServiceStruct.java @@ -19,18 +19,20 @@ import software.amazon.smithy.go.codegen.GoWriter; import software.amazon.smithy.utils.MapUtils; +import software.amazon.smithy.utils.SmithyInternalApi; /** * Generates the concrete type that serves traffic using a provided service implementation. */ +@SmithyInternalApi public final class ServiceStruct implements GoWriter.Writable { // TODO: ???????? name public static final String NAME = "ConcreteServiceTodoIdkWhatToCallThis"; public static final String OPTIONS_NAME = NAME + "Options"; - private final ProtocolGenerator protocolGenerator; + private final ServerProtocolGenerator protocolGenerator; - public ServiceStruct(ProtocolGenerator protocolGenerator) { + public ServiceStruct(ServerProtocolGenerator protocolGenerator) { this.protocolGenerator = protocolGenerator; } diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/TmpCodegenIntegration.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/TmpCodegenIntegration.java deleted file mode 100644 index 6f19aac28..000000000 --- a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/TmpCodegenIntegration.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package software.amazon.smithy.go.codegen.service; - -import software.amazon.smithy.codegen.core.SymbolProvider; -import software.amazon.smithy.go.codegen.GoDelegator; -import software.amazon.smithy.go.codegen.GoSettings; -import software.amazon.smithy.go.codegen.GoWriter; -import software.amazon.smithy.go.codegen.integration.GoIntegration; -import software.amazon.smithy.go.codegen.service.protocol.aws.AwsJson10ProtocolGenerator; -import software.amazon.smithy.model.Model; - -// TODO: setup invocation of codegen via cli, remove this -public class TmpCodegenIntegration implements GoIntegration { - @Override - public void writeAdditionalFiles( - GoSettings settings, Model model, SymbolProvider symbolProvider, GoDelegator goDelegator - ) { - final var service = settings.getService(model); - - // TODO should be resolved from model - final var protocolGenerator = new AwsJson10ProtocolGenerator(model, service, symbolProvider); - - goDelegator.useFileWriter("feat_svcgen.go", settings.getModuleName(), GoWriter.ChainWritable.of( - protocolGenerator.generateSource(), - new ServiceInterface(model, service, symbolProvider), - new NoopServiceStruct(model, service, symbolProvider), - new NotImplementedError(), - new ServiceStruct(protocolGenerator) - ).compose()); - } -} diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/protocol/HttpProtocolGenerator.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/protocol/HttpServerProtocolGenerator.java similarity index 82% rename from codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/protocol/HttpProtocolGenerator.java rename to codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/protocol/HttpServerProtocolGenerator.java index 7b0671071..2f812a1a3 100644 --- a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/protocol/HttpProtocolGenerator.java +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/protocol/HttpServerProtocolGenerator.java @@ -18,14 +18,22 @@ import static software.amazon.smithy.go.codegen.GoWriter.emptyGoTemplate; import static software.amazon.smithy.go.codegen.GoWriter.goTemplate; +import software.amazon.smithy.go.codegen.ApplicationProtocol; import software.amazon.smithy.go.codegen.GoStdlibTypes; import software.amazon.smithy.go.codegen.GoWriter; -import software.amazon.smithy.go.codegen.service.ProtocolGenerator; +import software.amazon.smithy.go.codegen.service.ServerProtocolGenerator; +import software.amazon.smithy.utils.SmithyInternalApi; /** * Implements base transport codegen for HTTP protocols. */ -public abstract class HttpProtocolGenerator implements ProtocolGenerator { +@SmithyInternalApi +public abstract class HttpServerProtocolGenerator implements ServerProtocolGenerator { + @Override + public ApplicationProtocol getApplicationProtocol() { + return ApplicationProtocol.createDefaultHttpApplicationProtocol(); + } + @Override public GoWriter.Writable generateSource() { return generateHttpHandler(); diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/protocol/aws/AwsJson10ProtocolGenerator.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/protocol/aws/AwsJson10ProtocolGenerator.java index 48922496a..5ac5e4f51 100644 --- a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/protocol/aws/AwsJson10ProtocolGenerator.java +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/protocol/aws/AwsJson10ProtocolGenerator.java @@ -17,22 +17,26 @@ import static software.amazon.smithy.go.codegen.GoWriter.goTemplate; +import software.amazon.smithy.aws.traits.protocols.AwsJson1_0Trait; import software.amazon.smithy.codegen.core.SymbolProvider; import software.amazon.smithy.go.codegen.GoStdlibTypes; import software.amazon.smithy.go.codegen.GoWriter; import software.amazon.smithy.go.codegen.service.NotImplementedError; import software.amazon.smithy.go.codegen.service.ServiceInterface; -import software.amazon.smithy.go.codegen.service.protocol.HttpProtocolGenerator; +import software.amazon.smithy.go.codegen.service.protocol.HttpServerProtocolGenerator; import software.amazon.smithy.model.Model; import software.amazon.smithy.model.knowledge.TopDownIndex; 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.utils.MapUtils; +import software.amazon.smithy.utils.SmithyInternalApi; /** * Implements the aws.protocols#awsJson1_0 protocol. */ -public final class AwsJson10ProtocolGenerator extends HttpProtocolGenerator { +@SmithyInternalApi +public final class AwsJson10ProtocolGenerator extends HttpServerProtocolGenerator { private final Model model; private final ServiceShape service; private final SymbolProvider symbolProvider; @@ -43,6 +47,12 @@ public AwsJson10ProtocolGenerator(Model model, ServiceShape service, SymbolProvi this.symbolProvider = symbolProvider; } + @Override + public ShapeId getProtocol() { + return AwsJson1_0Trait.ID; + } + + @Override public GoWriter.Writable generateSource() { return GoWriter.ChainWritable.of( diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/protocol/aws/SupportServerAwsJson10Protocol.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/protocol/aws/SupportServerAwsJson10Protocol.java new file mode 100644 index 000000000..45bd98a60 --- /dev/null +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/protocol/aws/SupportServerAwsJson10Protocol.java @@ -0,0 +1,36 @@ +/* + * Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.go.codegen.service.protocol.aws; + +import java.util.List; +import software.amazon.smithy.codegen.core.SymbolProvider; +import software.amazon.smithy.go.codegen.service.GoServerIntegration; +import software.amazon.smithy.go.codegen.service.ServerProtocolGenerator; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.utils.SmithyInternalApi; + +@SmithyInternalApi +public class SupportServerAwsJson10Protocol implements GoServerIntegration { + @Override + public List getServerProtocolGenerators( + Model model, + ServiceShape service, + SymbolProvider symbolProvider + ) { + return List.of(new AwsJson10ProtocolGenerator(model, service, symbolProvider)); + } +} diff --git a/codegen/smithy-go-codegen/src/main/resources/META-INF/services/software.amazon.smithy.build.SmithyBuildPlugin b/codegen/smithy-go-codegen/src/main/resources/META-INF/services/software.amazon.smithy.build.SmithyBuildPlugin index 9a66c8f58..e7c8bad78 100644 --- a/codegen/smithy-go-codegen/src/main/resources/META-INF/services/software.amazon.smithy.build.SmithyBuildPlugin +++ b/codegen/smithy-go-codegen/src/main/resources/META-INF/services/software.amazon.smithy.build.SmithyBuildPlugin @@ -1 +1,2 @@ software.amazon.smithy.go.codegen.GoCodegenPlugin +software.amazon.smithy.go.codegen.service.GoServerCodegenPlugin diff --git a/codegen/smithy-go-codegen/src/main/resources/META-INF/services/software.amazon.smithy.go.codegen.integration.GoIntegration b/codegen/smithy-go-codegen/src/main/resources/META-INF/services/software.amazon.smithy.go.codegen.integration.GoIntegration index 81a2895ce..d1bd764f6 100644 --- a/codegen/smithy-go-codegen/src/main/resources/META-INF/services/software.amazon.smithy.go.codegen.integration.GoIntegration +++ b/codegen/smithy-go-codegen/src/main/resources/META-INF/services/software.amazon.smithy.go.codegen.integration.GoIntegration @@ -15,5 +15,5 @@ software.amazon.smithy.go.codegen.integration.auth.AnonymousAuthScheme software.amazon.smithy.go.codegen.requestcompression.RequestCompression -# TODO: remove this when we can call into service codegen directly -software.amazon.smithy.go.codegen.service.TmpCodegenIntegration \ No newline at end of file +# Go SSDK +software.amazon.smithy.go.codegen.service.protocol.aws.SupportServerAwsJson10Protocol