Skip to content

Commit

Permalink
do timestamp and union serde
Browse files Browse the repository at this point in the history
  • Loading branch information
lucix-aws committed Feb 6, 2024
1 parent 3cb6835 commit 4c18cf9
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ public static final class Context {
public static final Symbol Context = SmithyGoDependency.CONTEXT.valueSymbol("Context");
}

public static final class Time {
public static final Symbol Time = SmithyGoDependency.TIME.pointableSymbol("Time");
}

public static final class Encoding {
public static final class Json {
public static final Symbol NewDecoder = SmithyGoDependency.JSON.valueSymbol("NewDecoder");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ public static final class Document {
}
}

public static final class Time {
public static final Symbol ParseDateTime = SmithyGoDependency.SMITHY_TIME.valueSymbol("ParseDateTime");
public static final Symbol FormatDateTime = SmithyGoDependency.SMITHY_TIME.valueSymbol("FormatDateTime");
}

public static final class Encoding {
public static final class Json {
public static final Symbol NewEncoder = SmithyGoDependency.SMITHY_JSON.valueSymbol("NewEncoder");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
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;

Expand Down Expand Up @@ -137,11 +138,12 @@ default void writeAdditionalFiles(
*
* @return Returns the list of protocol generators to register.
*/
default List<ServiceProtocolGenerator> getProtocolGenerators() {
default List<ServiceProtocolGenerator> getProtocolGenerators(
Model model, ServiceShape service, SymbolProvider symbolProvider
) {
return Collections.emptyList();
}


/**
* Processes the finalized model before runtime plugins are consumed and
* code generation starts. This plugin can be used to add RuntimeClientPlugins
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import static software.amazon.smithy.go.codegen.service.ServiceCodegenUtils.withUnit;

import java.util.List;
import software.amazon.smithy.codegen.core.CodegenException;
import software.amazon.smithy.codegen.core.SymbolDependency;
import software.amazon.smithy.codegen.core.SymbolProvider;
import software.amazon.smithy.codegen.core.WriterDelegator;
Expand All @@ -46,7 +47,6 @@
import software.amazon.smithy.go.codegen.StructureGenerator;
import software.amazon.smithy.go.codegen.SymbolVisitor;
import software.amazon.smithy.go.codegen.UnionGenerator;
import software.amazon.smithy.go.codegen.service.protocol.aws.AwsJson10ProtocolGenerator;
import software.amazon.smithy.model.knowledge.TopDownIndex;
import software.amazon.smithy.model.shapes.IntEnumShape;
import software.amazon.smithy.model.shapes.StringShape;
Expand Down Expand Up @@ -77,9 +77,8 @@ public void generateService(GenerateServiceDirective directive) {
var namespace = ((GoSettings) directive.settings()).getModuleName();
var delegator = directive.context().writerDelegator();
var settings = ((GoSettings) directive.settings());
var protocolGenerator = new AwsJson10ProtocolGenerator(
directive.model(), directive.service(), directive.symbolProvider()
);

var protocolGenerator = resolveProtocolGenerator(directive);

var model = directive.model();
var service = directive.service();
Expand All @@ -92,7 +91,6 @@ public void generateService(GenerateServiceDirective directive) {
.flatMap(it -> getShapesToSerde(model, it).stream())
.collect(toSet());


delegator.useFileWriter("service.go", namespace, GoWriter.ChainWritable.of(
new NotImplementedError(),
new ServiceInterface(directive.model(), directive.service(), directive.symbolProvider()),
Expand Down Expand Up @@ -193,4 +191,22 @@ public void generateIntEnumShape(GenerateIntEnumDirective directive) {
).run()
);
}

private ServiceProtocolGenerator resolveProtocolGenerator(
GenerateServiceDirective<GoCodegenContext, GoSettings> directive
) {
var model = directive.model();
var service = directive.service();
var symbolProvider = directive.symbolProvider();

var protocolGenerators = directive.context().integrations().stream()
.flatMap(it -> it.getProtocolGenerators(model, service, symbolProvider).stream())
.filter(it -> service.hasTrait(it.getProtocol()))
.toList();
if (protocolGenerators.isEmpty()) {
throw new CodegenException("could not resolve protocol generator");
}

return protocolGenerators.get(0);
}
}
Original file line number Diff line number Diff line change
@@ -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.integration;

import java.util.List;
import software.amazon.smithy.codegen.core.SymbolProvider;
import software.amazon.smithy.go.codegen.service.GoServiceIntegration;
import software.amazon.smithy.go.codegen.service.ServiceProtocolGenerator;
import software.amazon.smithy.go.codegen.service.protocol.aws.AwsJson10ProtocolGenerator;
import software.amazon.smithy.model.Model;
import software.amazon.smithy.model.shapes.ServiceShape;
import software.amazon.smithy.utils.ListUtils;

public class DefaultProtocols implements GoServiceIntegration {
@Override
public List<ServiceProtocolGenerator> getProtocolGenerators(
Model model, ServiceShape service, SymbolProvider symbolProvider
) {
return ListUtils.of(
new AwsJson10ProtocolGenerator(model, service, symbolProvider)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,8 @@ private GoWriter.Writable generateOpaqueAssert(Shape shape) {
goTemplate("[]interface{}");
case MAP, STRUCTURE, UNION ->
goTemplate("map[string]interface{}");
case DOCUMENT ->
throw new CodegenException("TODO: document is special");
default ->
throw new CodegenException("? " + shape.getType());
throw new CodegenException("Unsupported: " + shape.getType());
};
}

Expand All @@ -109,10 +107,10 @@ private GoWriter.Writable generateZeroValue(Shape shape) {
goTemplate("$T(\"\")", symbolProvider.toSymbol(shape));
case INT_ENUM ->
goTemplate("$T(0)", symbolProvider.toSymbol(shape));
case DOCUMENT ->
throw new CodegenException("TODO: document is special");
case TIMESTAMP ->
goTemplate("$T{}", GoStdlibTypes.Time.Time);
default ->
throw new CodegenException("? " + shape.getType());
throw new CodegenException("Unsupported: " + shape.getType());
};
}

Expand Down Expand Up @@ -215,9 +213,44 @@ yield goTemplate("""
.toList()
).compose(false)
));
case UNION -> goTemplate("// TODO (union)");
case UNION -> goTemplate("""
for key, serializedValue := range $ident:L {
$deserializeVariant:W
}
""",
MapUtils.of(
"type", symbolProvider.toSymbol(shape),
"ident", ident,
"deserializeVariant", GoWriter.ChainWritable.of(
shape.getAllMembers().entrySet().stream()
.map(it -> {
var target = model.expectShape(it.getValue().getTarget());
return goTemplate("""
if key == $variant:S {
variant, err := $deserialize:L(serializedValue)
if err != nil {
return nil, err
}
return variant, nil
}
""",
MapUtils.of(
"variant", it.getKey(),
"deserialize", getDeserializerName(normalize(target))
));
})
.toList()
).compose(false)
));
case TIMESTAMP -> goTemplate("""
dts, err := $T(serializedValue)
if err != nil {
return nil, err
}
return dts, nil
""", SmithyGoTypes.Time.ParseDateTime);
default ->
throw new CodegenException("? " + shape.getType());
throw new CodegenException("Unsupported: " + shape.getType());
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import software.amazon.smithy.model.shapes.MemberShape;
import software.amazon.smithy.model.shapes.Shape;
import software.amazon.smithy.model.shapes.StructureShape;
import software.amazon.smithy.model.shapes.TimestampShape;
import software.amazon.smithy.model.shapes.UnionShape;
import software.amazon.smithy.utils.MapUtils;
import software.amazon.smithy.utils.SmithyInternalApi;

Expand Down Expand Up @@ -84,17 +86,25 @@ private GoWriter.Writable generateSerializeValue(Shape shape) {
case BLOB -> goTemplate("jv.Base64EncodeBytes(v)");
case ENUM -> goTemplate("jv.String(string(v))");
case INT_ENUM -> goTemplate("jv.Integer(int32(v))");
case LIST, SET -> generateDeserializeList((CollectionShape) shape);
case TIMESTAMP -> generateSerializeTimestamp((TimestampShape) shape);
case LIST, SET -> generateSerializeList((CollectionShape) shape);
case MAP -> generateSerializeMap((MapShape) shape);
case STRUCTURE -> generateSerializeStruct((StructureShape) shape);
case TIMESTAMP -> goTemplate("// TODO timestamp");
case UNION -> goTemplate("// TODO union");
case UNION -> generateSerializeUnion((UnionShape) shape);
default ->
throw new CodegenException("? " + shape.getType());
throw new CodegenException("Unsupported: " + shape.getType());
};
}

private GoWriter.Writable generateDeserializeList(CollectionShape shape) {
private GoWriter.Writable generateSerializeTimestamp(TimestampShape shape) {
return goTemplate("""
if v != nil {
jv.String($T(*v))
}
""", SmithyGoTypes.Time.FormatDateTime);
}

private GoWriter.Writable generateSerializeList(CollectionShape shape) {
var target = normalize(model.expectShape(shape.getMember().getTarget()));
var symbol = symbolProvider.toSymbol(shape);
var targetSymbol = symbolProvider.toSymbol(target);
Expand Down Expand Up @@ -191,4 +201,32 @@ private GoWriter.Writable serializeMember(MemberShape member, Shape target) {
"serialize", getSerializerName(target)
));
}

private GoWriter.Writable generateSerializeUnion(UnionShape shape) {
return goTemplate("""
mp := jv.Object()
defer mp.Close()
$W
""", GoWriter.ChainWritable.of(
shape.getAllMembers().values().stream()
.map(this::generateSerializeVariant)
.toList()
).compose(false));
}

private GoWriter.Writable generateSerializeVariant(MemberShape member) {
var target = normalize(model.expectShape(member.getTarget()));
return goTemplate("""
if variant, ok := v.($variant:P); ok {
if err := $serialize:L(variant, mp.Key($key:S)); err != nil {
return err
}
}
""",
MapUtils.of(
"variant", symbolProvider.toSymbol(target),
"serialize", getSerializerName(target),
"key", member.getMemberName()
));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,4 @@ software.amazon.smithy.go.codegen.endpoints.EndpointClientPluginsGenerator
software.amazon.smithy.go.codegen.integration.auth.SigV4AuthScheme
software.amazon.smithy.go.codegen.integration.auth.AnonymousAuthScheme

software.amazon.smithy.go.codegen.requestcompression.RequestCompression

# Go SSDK
software.amazon.smithy.go.codegen.requestcompression.RequestCompression
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
software.amazon.smithy.go.codegen.service.integration.DefaultProtocols

0 comments on commit 4c18cf9

Please sign in to comment.