diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoStdlibTypes.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoStdlibTypes.java index f818ce7d1..ba31d4170 100644 --- a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoStdlibTypes.java +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoStdlibTypes.java @@ -30,6 +30,7 @@ public static final class Context { public static final class Fmt { public static final Symbol Errorf = SmithyGoDependency.FMT.valueSymbol("Errorf"); + public static final Symbol Sprintf = SmithyGoDependency.FMT.valueSymbol("Sprintf"); } public static final class Net { diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/NoopServiceStruct.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/NoopServiceStruct.java new file mode 100644 index 000000000..4c4936a37 --- /dev/null +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/NoopServiceStruct.java @@ -0,0 +1,91 @@ +/* + * 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 static software.amazon.smithy.go.codegen.GoWriter.goTemplate; + +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.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.utils.MapUtils; + +/** + * Generates a no-op implementation of the service that returns 501 Not Implemented for every operation. + */ +public final class NoopServiceStruct implements GoWriter.Writable { + public static final String NAME = "NoopService"; + + private final Model model; + private final ServiceShape service; + private final SymbolProvider symbolProvider; + + public NoopServiceStruct(Model model, ServiceShape service, SymbolProvider symbolProvider) { + this.model = model; + this.service = service; + this.symbolProvider = symbolProvider; + } + + @Override + public void accept(GoWriter writer) { + writer.write(generateStruct()); + } + + private GoWriter.Writable generateStruct() { + return goTemplate(""" + type $struct:L struct{} + + var _ $interface:L = (*$struct:L)(nil) + + $operations:W + """, + MapUtils.of( + "struct", NAME, + "interface", ServiceInterface.NAME, + "operations", generateOperations() + )); + } + + private GoWriter.Writable generateOperations() { + return GoWriter.ChainWritable.of( + TopDownIndex.of(model).getContainedOperations(service).stream() + .map(this::generateOperation) + .toList() + ).compose(); + } + + private GoWriter.Writable generateOperation(OperationShape operation) { + final var operationSymbol = symbolProvider.toSymbol(operation); + return goTemplate(""" + func (*$struct:L) $operation:T($context:T, $input:P) ($output:P, error) { + return nil, &$notImplemented:L{$operationName:S} + } + """, + MapUtils.of( + "struct", NAME, + "operation", operationSymbol, + "context", GoStdlibTypes.Context.Context, + "input", symbolProvider.toSymbol(model.expectShape(operation.getInputShape())), + "output", symbolProvider.toSymbol(model.expectShape(operation.getOutputShape())), + "notImplemented", NotImplementedError.NAME, + "operationName", operationSymbol.getName() + ) + ); + } +} diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/NotImplementedError.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/NotImplementedError.java new file mode 100644 index 000000000..b442c6ad4 --- /dev/null +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/NotImplementedError.java @@ -0,0 +1,52 @@ +/* + * 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 static software.amazon.smithy.go.codegen.GoWriter.goTemplate; + +import software.amazon.smithy.go.codegen.GoStdlibTypes; +import software.amazon.smithy.go.codegen.GoWriter; +import software.amazon.smithy.utils.MapUtils; + +/** + * Generates the NotImplemented error sentinel to be returned when a service doesn't support a specific action. + */ +public final class NotImplementedError implements GoWriter.Writable { + public static final String NAME = "NotImplemented"; + + @Override + public void accept(GoWriter writer) { + writer.write(generateStruct()); + } + + private GoWriter.Writable generateStruct() { + return goTemplate(""" + type $struct:L struct { + Operation string + } + + var _ error = (*$struct:L)(nil) + + func (err *$struct:L) Error() string { + return $sprintf:T("%s is not implemented", err.Operation) + } + """, + MapUtils.of( + "struct", NAME, + "sprintf", GoStdlibTypes.Fmt.Sprintf + )); + } +} 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/ProtocolGenerator.java index 2c9c7caac..5858affeb 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/ProtocolGenerator.java @@ -20,7 +20,11 @@ public interface ProtocolGenerator { /** * Generate the operation routing logic for this protocol. - * @return The writable operation handler. */ GoWriter.Writable generateHandler(); + + /** + * Generate the serializing logic for the builtin NotImplemented error. + */ + GoWriter.Writable generateSerializeNotImplemented(); } diff --git a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/ServiceInterface.java b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/ServiceInterface.java index abd7967c0..2b2aaa27a 100644 --- a/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/ServiceInterface.java +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/ServiceInterface.java @@ -65,7 +65,7 @@ private GoWriter.Writable generateOperations() { private GoWriter.Writable generateOperation(OperationShape operation) { return goTemplate( - "$operation:T($context:L, $input:P) ($output:P, error)", + "$operation:T($context:T, $input:P) ($output:P, error)", MapUtils.of( "operation", symbolProvider.toSymbol(operation), "context", GoStdlibTypes.Context.Context, 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 new file mode 100644 index 000000000..76bb6ffce --- /dev/null +++ b/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/service/TmpCodegenIntegration.java @@ -0,0 +1,38 @@ +/* + * 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.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); + goDelegator.useFileWriter("feat_svcgen.go", settings.getModuleName(), GoWriter.ChainWritable.of( + new ServiceInterface(model, service, symbolProvider), + new NoopServiceStruct(model, service, symbolProvider), + new NotImplementedError() + ).compose()); + } +} 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 09af27932..81a2895ce 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 @@ -14,3 +14,6 @@ software.amazon.smithy.go.codegen.integration.auth.SigV4AuthScheme 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