Skip to content

Commit

Permalink
feat: add rpcv2 cbor support (#509)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucix-aws authored Mar 29, 2024
1 parent c5b40f4 commit fba1006
Show file tree
Hide file tree
Showing 47 changed files with 6,471 additions and 12 deletions.
1 change: 1 addition & 0 deletions codegen/smithy-go-codegen/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ dependencies {
api("org.jsoup:jsoup:1.14.1")
api("software.amazon.smithy:smithy-rules-engine:$smithyVersion")
implementation("software.amazon.smithy:smithy-protocol-test-traits:$smithyVersion")
api("software.amazon.smithy:smithy-protocol-traits:$smithyVersion")
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import java.util.TreeSet;
import java.util.logging.Logger;
import software.amazon.smithy.go.codegen.trait.BackfilledInputOutputTrait;
import software.amazon.smithy.model.Model;
import software.amazon.smithy.model.knowledge.TopDownIndex;
import software.amazon.smithy.model.shapes.AbstractShapeBuilder;
Expand Down Expand Up @@ -83,6 +84,7 @@ private static StructureShape emptyOperationStructure(ServiceShape service, Shap
return StructureShape.builder()
.id(ShapeId.fromParts(CodegenUtils.getSyntheticTypeNamespace(), opShapeId.getName(service) + suffix))
.addTrait(Synthetic.builder().build())
.addTrait(new BackfilledInputOutputTrait())
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import software.amazon.smithy.utils.StringUtils;

public final class EventStreamGenerator {
public static final String AMZ_CONTENT_TYPE = "application/vnd.amazon.eventstream";

private static final String EVENT_STREAM_FILE = "eventstream.go";

private final GoSettings settings;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,42 @@ public Symbol valueSymbol(String name) {
return SymbolUtils.createValueSymbolBuilder(name, this).build();
}

/**
* Creates a Symbol for a `const` exported by this package.
* @param name The name.
* @return The symbol.
*/
public Symbol constSymbol(String name) {
return SymbolUtils.createValueSymbolBuilder(name, this).build();
}

/**
* Creates a Symbol for a `func` exported by this package.
* @param name The name.
* @return The symbol.
*/
public Symbol func(String name) {
return SymbolUtils.createValueSymbolBuilder(name, this).build();
}

/**
* Creates a Symbol for a `struct` exported by this package.
* @param name The name.
* @return The symbol.
*/
public Symbol struct(String name) {
return SymbolUtils.createPointableSymbolBuilder(name, this).build();
}

/**
* Creates a Symbol for a `Value` exported by this package.
* @param name The name.
* @return The symbol.
*/
public Symbol interfaceSymbol(String name) {
return SymbolUtils.createValueSymbolBuilder(name, this).build();
}

/**
* Creates a pointable Symbol for a name exported by this package.
* @param name The name.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,35 @@
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import software.amazon.smithy.aws.traits.protocols.AwsJson1_0Trait;
import software.amazon.smithy.aws.traits.protocols.AwsJson1_1Trait;
import software.amazon.smithy.aws.traits.protocols.AwsQueryTrait;
import software.amazon.smithy.aws.traits.protocols.Ec2QueryTrait;
import software.amazon.smithy.aws.traits.protocols.RestJson1Trait;
import software.amazon.smithy.aws.traits.protocols.RestXmlTrait;
import software.amazon.smithy.codegen.core.CodegenException;
import software.amazon.smithy.model.Model;
import software.amazon.smithy.model.knowledge.ServiceIndex;
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.protocol.traits.Rpcv2CborTrait;
import software.amazon.smithy.utils.SmithyInternalApi;

/**
* Settings used by {@link GoCodegenPlugin}.
*/
@SmithyInternalApi
public final class GoSettings {
public static final Set<ShapeId> PROTOCOLS_BY_PRIORITY = Set.of(
Rpcv2CborTrait.ID,
AwsJson1_0Trait.ID,
AwsJson1_1Trait.ID,
RestJson1Trait.ID,
RestXmlTrait.ID,
AwsQueryTrait.ID,
Ec2QueryTrait.ID
);

private static final String SERVICE = "service";
private static final String MODULE_NAME = "module";
Expand Down Expand Up @@ -247,7 +263,10 @@ public ShapeId resolveServiceProtocol(

Set<ShapeId> resolvedProtocols = serviceIndex.getProtocols(service).keySet();

return resolvedProtocols.stream()
var byPriority = PROTOCOLS_BY_PRIORITY.stream()
.filter(resolvedProtocols::contains)
.toList();
return byPriority.stream()
.filter(supportedProtocolTraits::contains)
.findFirst()
.orElseThrow(() -> new UnresolvableProtocolException(String.format(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
public final class GoStdlibTypes {
private GoStdlibTypes() { }

public static final class Bytes {
public static final Symbol NewReader = SmithyGoDependency.BYTES.valueSymbol("NewReader");
}

public static final class Context {
public static final Symbol Context = SmithyGoDependency.CONTEXT.valueSymbol("Context");
public static final Symbol Background = SmithyGoDependency.CONTEXT.valueSymbol("Background");
Expand Down Expand Up @@ -55,13 +59,23 @@ public static final class Fmt {
public static final Symbol Sprintf = SmithyGoDependency.FMT.valueSymbol("Sprintf");
}

public static final class Io {
public static final Symbol ReadAll = SmithyGoDependency.IO.valueSymbol("ReadAll");
public static final Symbol Copy = SmithyGoDependency.IO.valueSymbol("Copy");

public static final class IoUtil {
public static final Symbol Discard = SmithyGoDependency.IOUTIL.valueSymbol("Discard");
}
}

public static final class Net {
public static final class Http {
public static final Symbol Request = SmithyGoDependency.NET_HTTP.pointableSymbol("Request");
public static final Symbol Response = SmithyGoDependency.NET_HTTP.pointableSymbol("Response");
public static final Symbol Server = SmithyGoDependency.NET_HTTP.pointableSymbol("Server");
public static final Symbol Handler = SmithyGoDependency.NET_HTTP.valueSymbol("Handler");
public static final Symbol ResponseWriter = SmithyGoDependency.NET_HTTP.valueSymbol("ResponseWriter");
public static final Symbol MethodPost = SmithyGoDependency.NET_HTTP.valueSymbol("MethodPost");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public final class SmithyGoDependency {
public static final GoDependency SMITHY_HTTP_BINDING = smithy("encoding/httpbinding");
public static final GoDependency SMITHY_JSON = smithy("encoding/json", "smithyjson");
public static final GoDependency SMITHY_XML = smithy("encoding/xml", "smithyxml");
public static final GoDependency SMITHY_CBOR = smithy("encoding/cbor", "smithycbor");
public static final GoDependency SMITHY_IO = smithy("io", "smithyio");
public static final GoDependency SMITHY_LOGGING = smithy("logging");
public static final GoDependency SMITHY_PTR = smithy("ptr");
Expand All @@ -68,6 +69,7 @@ public final class SmithyGoDependency {
public static final GoDependency SMITHY_WAITERS = smithy("waiter", "smithywaiter");
public static final GoDependency SMITHY_DOCUMENT = smithy("document", "smithydocument");
public static final GoDependency SMITHY_DOCUMENT_JSON = smithy("document/json", "smithydocumentjson");
public static final GoDependency SMITHY_DOCUMENT_CBOR = smithy("document/cbor", "smithydocumentcbor");
public static final GoDependency SMITHY_SYNC = smithy("sync", "smithysync");
public static final GoDependency SMITHY_AUTH = smithy("auth", "smithyauth");
public static final GoDependency SMITHY_AUTH_BEARER = smithy("auth/bearer");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public static final class Smithy {
public static final Symbol Properties = SmithyGoDependency.SMITHY.pointableSymbol("Properties");
public static final Symbol OperationError = SmithyGoDependency.SMITHY.pointableSymbol("OperationError");
public static final Symbol InvalidParamsError = SmithyGoDependency.SMITHY.pointableSymbol("InvalidParamsError");
public static final Symbol SerializationError = SmithyGoDependency.SMITHY.pointableSymbol("SerializationError");

public static final class Document {
public static final Symbol NoSerde = SmithyGoDependency.SMITHY_DOCUMENT.pointableSymbol("NoSerde");
Expand All @@ -39,15 +40,47 @@ public static final class Time {
public static final Symbol FormatDateTime = SmithyGoDependency.SMITHY_TIME.valueSymbol("FormatDateTime");
}

public static final class Rand {
public static final Symbol NewUUID = SmithyGoDependency.SMITHY_RAND.valueSymbol("NewUUID");
}

public static final class Encoding {
public static final class Json {
public static final Symbol NewEncoder = SmithyGoDependency.SMITHY_JSON.valueSymbol("NewEncoder");
public static final Symbol Value = SmithyGoDependency.SMITHY_JSON.valueSymbol("Value");
}

public static final class Cbor {
public static final Symbol Encode = SmithyGoDependency.SMITHY_CBOR.valueSymbol("Encode");
public static final Symbol Decode = SmithyGoDependency.SMITHY_CBOR.valueSymbol("Decode");
public static final Symbol Value = SmithyGoDependency.SMITHY_CBOR.valueSymbol("Value");
public static final Symbol Uint = SmithyGoDependency.SMITHY_CBOR.valueSymbol("Uint");
public static final Symbol NegInt = SmithyGoDependency.SMITHY_CBOR.valueSymbol("NegInt");
public static final Symbol Slice = SmithyGoDependency.SMITHY_CBOR.valueSymbol("Slice");
public static final Symbol String = SmithyGoDependency.SMITHY_CBOR.valueSymbol("String");
public static final Symbol List = SmithyGoDependency.SMITHY_CBOR.valueSymbol("List");
public static final Symbol Map = SmithyGoDependency.SMITHY_CBOR.valueSymbol("Map");
public static final Symbol Tag = SmithyGoDependency.SMITHY_CBOR.pointableSymbol("Tag");
public static final Symbol Bool = SmithyGoDependency.SMITHY_CBOR.valueSymbol("Bool");
public static final Symbol Nil = SmithyGoDependency.SMITHY_CBOR.pointableSymbol("Nil");
public static final Symbol Undefined = SmithyGoDependency.SMITHY_CBOR.pointableSymbol("Undefined");
public static final Symbol Float32 = SmithyGoDependency.SMITHY_CBOR.valueSymbol("Float32");
public static final Symbol Float64 = SmithyGoDependency.SMITHY_CBOR.valueSymbol("Float64");
public static final Symbol EncodeRaw = SmithyGoDependency.SMITHY_CBOR.valueSymbol("EncodeRaw");
public static final Symbol AsInt8 = SmithyGoDependency.SMITHY_CBOR.valueSymbol("AsInt8");
public static final Symbol AsInt16 = SmithyGoDependency.SMITHY_CBOR.valueSymbol("AsInt16");
public static final Symbol AsInt32 = SmithyGoDependency.SMITHY_CBOR.valueSymbol("AsInt32");
public static final Symbol AsInt64 = SmithyGoDependency.SMITHY_CBOR.valueSymbol("AsInt64");
public static final Symbol AsFloat32 = SmithyGoDependency.SMITHY_CBOR.valueSymbol("AsFloat32");
public static final Symbol AsFloat64 = SmithyGoDependency.SMITHY_CBOR.valueSymbol("AsFloat64");
public static final Symbol AsTime = SmithyGoDependency.SMITHY_CBOR.valueSymbol("AsTime");
}
}

public static final class Rand {
public static final Symbol NewUUID = SmithyGoDependency.SMITHY_RAND.valueSymbol("NewUUID");
public static final class Document {
public static final class Cbor {
public static final Symbol NewEncoder = SmithyGoDependency.SMITHY_DOCUMENT_CBOR.valueSymbol("NewEncoder");
}
}

public static final class Ptr {
Expand All @@ -57,6 +90,9 @@ public static final class Ptr {
public static final Symbol Int16 = SmithyGoDependency.SMITHY_PTR.valueSymbol("Int16");
public static final Symbol Int32 = SmithyGoDependency.SMITHY_PTR.valueSymbol("Int32");
public static final Symbol Int64 = SmithyGoDependency.SMITHY_PTR.valueSymbol("Int64");
public static final Symbol Float32 = SmithyGoDependency.SMITHY_PTR.valueSymbol("Float32");
public static final Symbol Float64 = SmithyGoDependency.SMITHY_PTR.valueSymbol("Float64");
public static final Symbol Time = SmithyGoDependency.SMITHY_PTR.valueSymbol("Time");
}

public static final class Middleware {
Expand Down Expand Up @@ -84,6 +120,7 @@ public static final class Middleware {
public static final class Transport {
public static final class Http {
public static final Symbol Request = SmithyGoDependency.SMITHY_HTTP_TRANSPORT.pointableSymbol("Request");
public static final Symbol Response = SmithyGoDependency.SMITHY_HTTP_TRANSPORT.pointableSymbol("Response");
public static final Symbol NewStackRequest = SmithyGoDependency.SMITHY_HTTP_TRANSPORT.valueSymbol("NewStackRequest");
public static final Symbol NewClientHandler = SmithyGoDependency.SMITHY_HTTP_TRANSPORT.valueSymbol("NewClientHandler");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,4 +210,17 @@ public static Symbol getReference(Symbol symbol) {
public static Symbol buildPackageSymbol(String name) {
return Symbol.builder().name(name).build();
}

public static Symbol buildSymbol(String name, String namespace) {
return Symbol.builder()
.name(name)
.namespace(namespace, ".")
.build();
}

public static boolean isNilable(Symbol symbol) {
return isPointable(symbol)
|| symbol.getProperty(SymbolUtils.GO_SLICE).isPresent()
|| symbol.getProperty(SymbolUtils.GO_MAP).isPresent();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* 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.integration;

import java.util.List;
import software.amazon.smithy.go.codegen.protocol.rpc2.cbor.Rpc2CborProtocolGenerator;
import software.amazon.smithy.utils.ListUtils;

public class DefaultProtocols implements GoIntegration {
@Override
public List<ProtocolGenerator> getProtocolGenerators() {
return ListUtils.of(new Rpc2CborProtocolGenerator());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,11 @@ protected void generateTestCaseValues(GoWriter writer, HttpRequestTestCase testC
"return smithytesting.CompareURLFormReaderBytes(actual, []byte(`%s`))",
body);
break;
case "application/cbor":
compareFunc = String.format(
"return smithytesting.CompareCBOR(actual, `%s`)",
body);
break;
default:
compareFunc = String.format(
"return smithytesting.CompareReaderBytes(actual, []byte(`%s`))",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,20 @@ protected void generateTestCaseValues(GoWriter writer, HttpResponseTestCase test
writeStructField(writer, "BodyMediaType", "$S", mediaType);
});
testCase.getBody().ifPresent(body -> {
writeStructField(writer, "Body", "[]byte(`$L`)", body);
var mediaType = testCase.getBodyMediaType().orElse("");
if (mediaType.equalsIgnoreCase("application/cbor")) {
writeStructField(writer, "Body", """
func() []byte {
p, err := $T.DecodeString(`$L`)
if err != nil {
panic(err)
}
return p
}()""", SmithyGoDependency.BASE64.func("StdEncoding"), body);
} else {
writeStructField(writer, "Body", "[]byte(`$L`)", body);
}
});

writeStructField(writer, "ExpectError", errorShape, testCase.getParams());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,20 @@ protected void generateTestCaseValues(GoWriter writer, HttpResponseTestCase test
writeStructField(writer, "BodyMediaType", "$S", mediaType);
});
testCase.getBody().ifPresent(body -> {
writeStructField(writer, "Body", "[]byte(`$L`)", body);
var mediaType = testCase.getBodyMediaType().orElse("");
if (mediaType.equalsIgnoreCase("application/cbor")) {
writeStructField(writer, "Body", """
func() []byte {
p, err := $T.DecodeString(`$L`)
if err != nil {
panic(err)
}
return p
}()""", SmithyGoDependency.BASE64.func("StdEncoding"), body);
} else {
writeStructField(writer, "Body", "[]byte(`$L`)", body);
}
});

writeStructField(writer, "ExpectResult", outputShape, testCase.getParams());
Expand Down
Loading

0 comments on commit fba1006

Please sign in to comment.