Skip to content

Commit

Permalink
codegen: upgrade to smithy 1.27.x
Browse files Browse the repository at this point in the history
Update serializing empty lists for query protocols (see references)
to pass protocol tests.

Previous Behavior:

`{ "ListArg": [] }` serializes to ``.

Current Behavior:

`{ "ListArg": [] }` serializes to `?ListArg=`.

References:

- smithy-lang/smithy#1444
- [AWS query
  protocol](https://awslabs.github.io/smithy/2.0/aws/protocols/aws-query-protocol.html)
- [AWS EC2 query
  protocol](https://awslabs.github.io/smithy/2.0/aws/protocols/aws-ec2-query-protocol.html)
  • Loading branch information
Steven Yuan committed Jan 30, 2023
1 parent 968965a commit 0b8d05e
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 4 deletions.
31 changes: 31 additions & 0 deletions .changelog/e0727d8e716742fdbb16b62e64b20456.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"id": "e0727d8e-7167-42fd-bb16-b62e64b20456",
"type": "feature",
"description": "Upgrade smithy to 1.27.x, updating query protocol serializers.",
"modules": [
"internal/protocoltest/awsrestjson",
"internal/protocoltest/ec2query",
"internal/protocoltest/jsonrpc",
"internal/protocoltest/jsonrpc10",
"internal/protocoltest/query",
"internal/protocoltest/restxml",
"service/autoscaling",
"service/cloudformation",
"service/cloudsearch",
"service/cloudwatch",
"service/docdb",
"service/ec2",
"service/elasticache",
"service/elasticbeanstalk",
"service/elasticloadbalancing",
"service/elasticloadbalancingv2",
"service/iam",
"service/neptune",
"service/rds",
"service/redshift",
"service/ses",
"service/sns",
"service/sqs",
"service/sts"
]
}
17 changes: 17 additions & 0 deletions aws/protocol/query/array.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,20 @@ func (a *Array) Value() Value {
// Lists can't have flat members
return newValue(a.values, fmt.Sprintf("%s.%d", prefix, a.size), false)
}

// Empty allows empty Query Array URI encoding, e.g.
//
// "ListArg": [] -> ?ListArg=
//
// If this method is not called on an empty Query Array, it will
// not be serialized when encoded.
//
// The method should ONLY be used if the Array is known to be empty.
func (a *Array) Empty() {
// If the Array is not empty, return to avoid wrong encoding
if a.size != 0 {
return
}
// Set value of prefix to empty string (no text)
newValue(a.values, a.prefix, false).String("")
}
16 changes: 16 additions & 0 deletions aws/protocol/query/encoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ func TestEncode(t *testing.T) {
},
Expect: []byte(`list.spam.1=spam&list.spam.2=eggs`),
},
"empty list": {
Encode: func(e *Encoder) error {
list := e.Object().Key("ListArg").Array("member")
list.Empty()
return e.Encode()
},
Expect: []byte(`ListArg=`),
},
"flat list": {
Encode: func(e *Encoder) error {
list := e.Object().FlatKey("list").Array("spam")
Expand All @@ -44,6 +52,14 @@ func TestEncode(t *testing.T) {
},
Expect: []byte(`list.1=spam&list.2=eggs`),
},
"empty flat list": {
Encode: func(e *Encoder) error {
list := e.Object().FlatKey("ListArg").Array("member")
list.Empty()
return e.Encode()
},
Expect: []byte(`ListArg=`),
},
"map": {
Encode: func(e *Encoder) error {
mapValue := e.Object().Key("map").Map("key", "value")
Expand Down
2 changes: 1 addition & 1 deletion codegen/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
smithyVersion=1.25.2
smithyVersion=[1.27.0,1.28.0[
smithyGradleVersion=0.6.0
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import software.amazon.smithy.model.shapes.MapShape;
import software.amazon.smithy.model.shapes.MemberShape;
import software.amazon.smithy.model.shapes.Shape;
import software.amazon.smithy.model.shapes.ShapeType;
import software.amazon.smithy.model.shapes.StructureShape;
import software.amazon.smithy.model.shapes.UnionShape;
import software.amazon.smithy.model.traits.EnumTrait;
Expand Down Expand Up @@ -75,10 +76,16 @@ protected void serializeCollection(GenerationContext context, CollectionShape sh
MemberShape member = shape.getMember();
Shape target = context.getModel().expectShape(member.getTarget());

// If the list is empty, exit early to avoid extra effort.
writer.write("if len(v) == 0 { return nil }");
String arrayName = getSerializedLocationName(member, "member");
writer.write("array := value.Array($S)", arrayName);

// If the list is empty, serialize an empty query value.
writer.write("""
if len(v) == 0 {
array.Empty()
return nil
}""");

writer.write("array := value.Array($S)", getSerializedLocationName(member, "member"));
writer.write("");

writer.openBlock("for i := range v {", "}", () -> {
Expand Down

0 comments on commit 0b8d05e

Please sign in to comment.