diff --git a/README.md b/README.md index 088f17049c9..eb274eb7c96 100644 --- a/README.md +++ b/README.md @@ -19,16 +19,16 @@ shapes. namespace example.weather service Weather { - version: "2006-03-01", - resources: [City], + version: "2006-03-01" + resources: [City] operations: [GetCurrentTime] } resource City { - identifiers: { cityId: CityId }, - read: GetCity, - list: ListCities, - resources: [Forecast], + identifiers: { cityId: CityId } + read: GetCity + list: ListCities + resources: [Forecast] } // See the full example at https://awslabs.github.io/smithy/quickstart.html#complete-example diff --git a/docs/source/1.0/guides/converting-to-openapi.rst b/docs/source/1.0/guides/converting-to-openapi.rst index 05d5502c4df..6921a38789d 100644 --- a/docs/source/1.0/guides/converting-to-openapi.rst +++ b/docs/source/1.0/guides/converting-to-openapi.rst @@ -696,8 +696,8 @@ For example, given the following Smithy model: @restJson1 @httpApiKeyAuth(name: "x-api-key", in: "header") service Foo { - version: "2006-03-01", - operations: [ExampleOperation], + version: "2006-03-01" + operations: [ExampleOperation] } @http(method: "GET", uri: "/") @@ -957,12 +957,13 @@ The following Smithy model: @sigv4(name: "service") @authorizer("foo") @authorizers( - foo: {scheme: sigv4, type: "aws", uri: "arn:foo"}, - baz: {scheme: sigv4, type: "aws", uri: "arn:foo"}) + foo: {scheme: sigv4, type: "aws", uri: "arn:foo"} + baz: {scheme: sigv4, type: "aws", uri: "arn:foo"} + ) service Example { - version: "2019-06-17", - operations: [OperationA, OperationB], - resources: [ResourceA, ResourceB], + version: "2019-06-17" + operations: [OperationA, OperationB] + resources: [ResourceA, ResourceB] } // Inherits the authorizer of the service @@ -1205,8 +1206,8 @@ The following Smithy model enables API Gateway's API key usage plans on the @authorizer("api_key") @authorizers(api_key: {scheme: "smithy.api#httpApiKeyAuth"}) service Example { - version: "2019-06-17", - operations: [OperationA], + version: "2019-06-17" + operations: [OperationA] } operation OperationA {} diff --git a/docs/source/1.0/guides/generating-cloudformation-resources.rst b/docs/source/1.0/guides/generating-cloudformation-resources.rst index a4ca3e8a3e0..695ce356952 100644 --- a/docs/source/1.0/guides/generating-cloudformation-resources.rst +++ b/docs/source/1.0/guides/generating-cloudformation-resources.rst @@ -116,8 +116,8 @@ generate one Resource Schema with the ``typeName`` of ``AWS:Queues:Queue``. @service(sdkId: "Queues", cloudFormationName: "Queues") service QueueService { - version: "2020-07-02", - resources: [Queue], + version: "2020-07-02" + resources: [Queue] } .. important:: diff --git a/docs/source/1.0/guides/model-linters.rst b/docs/source/1.0/guides/model-linters.rst index 9f5265fb14a..7120c6b31b8 100644 --- a/docs/source/1.0/guides/model-linters.rst +++ b/docs/source/1.0/guides/model-linters.rst @@ -187,13 +187,13 @@ Example: metadata validators = [{ id: "FooReservedWords" - name: "ReservedWords", + name: "ReservedWords" configuration: { reserved: [ { - words: ["Codename"], - reason: "This is the internal project name.", - }, + words: ["Codename"] + reason: "This is the internal project name." + } ] } }] @@ -341,13 +341,13 @@ Example: $version: "1.0" metadata validators = [{ - name: "StandardOperationVerb", + name: "StandardOperationVerb" configuration: { - verbs: ["Register", "Deregister", "Associate"], - prefixes: ["Batch"], + verbs: ["Register", "Deregister", "Associate"] + prefixes: ["Batch"] suggestAlternatives: { - "Make": ["Create"], - "Transition": ["Update"], + "Make": ["Create"] + "Transition": ["Update"] } } }] @@ -676,7 +676,7 @@ example warns each time the word "meow" appears in documentation: metadata validators = [ { - name: "ForbiddenDocumentation", + name: "ForbiddenDocumentation" configuration: { forbid: ["meow"] } @@ -695,9 +695,9 @@ example warns each time the word "meow" appears in documentation: metadata validators = [ { - name: "EmitEachSelector", - id: "ForbiddenDocumentation", - message: "Documentation uses forbidden text", + name: "EmitEachSelector" + id: "ForbiddenDocumentation" + message: "Documentation uses forbidden text" configuration: { selector: "[trait|documentation*='meow']" } diff --git a/docs/source/1.0/guides/style-guide.rst b/docs/source/1.0/guides/style-guide.rst index eff772c7797..56e564705e0 100644 --- a/docs/source/1.0/guides/style-guide.rst +++ b/docs/source/1.0/guides/style-guide.rst @@ -39,13 +39,15 @@ Smithy models SHOULD resemble the following example: structure MyStructure { /// Documentation about the member. @required - foo: String, + foo: String } // Example of creating custom traits. @trait(selector: "string") structure myTrait {} +* Each statement should appear on its own line. + File encoding ------------- @@ -93,10 +95,65 @@ Whitespace 4. Members of an object are not horizontally aligned. -Trailing commas ---------------- +Commas +------ + +Omit commas everywhere except in traits or node values defined on a +single line. + +Do: + +.. code-block:: smithy + + $version: "1.0" + + metadata validators = [{ + name: "StandardOperationVerb" + configuration: { + verbs: ["Get", "Delete", "Create", "Update"] + prefixes: ["Batch"] + } + }] + + namespace smithy.example.namespace -Include trailing commas to limit diff noise. + /// Gets a resource by ID. + @http(method: "GET", uri: "/message/{userId}") + operation GetMessage { + input: GetMessageInput + output: GetMessageOutput + errors: [ + ValidationError + ResourceNotFoundError + ] + } + +Do not: + +.. code-block:: smithy + + $version: "1.0" + + metadata validators = [{ + name: "StandardOperationVerb", + configuration: { + verbs: ["Get" "Delete" "Create" "Update"], + prefixes: ["Batch"], + }, + },] + + namespace smithy.example.namespace + + /// Gets a resource by ID. + @http(method: "GET" uri: "/message/{userId}") + operation GetMessage { + input: GetMessageInput, + output: GetMessageOutput, + errors: [ + ValidationError, + ResourceNotFoundError, + ], + } Naming diff --git a/docs/source/1.0/spec/aws/amazon-apigateway.rst b/docs/source/1.0/spec/aws/amazon-apigateway.rst index ba492af7e71..01464e935b5 100644 --- a/docs/source/1.0/spec/aws/amazon-apigateway.rst +++ b/docs/source/1.0/spec/aws/amazon-apigateway.rst @@ -199,14 +199,15 @@ An *authorizer* definition is a structure that supports the following members: @authorizer("arbitrary-name") @authorizers( "arbitrary-name": { - scheme: sigv4, - type: "request", - uri: "arn:foo:baz", - credentials: "arn:foo:bar", - identitySource: "mapping.expression", - identityValidationExpression: "[A-Z]+", + scheme: sigv4 + type: "request" + uri: "arn:foo:baz" + credentials: "arn:foo:bar" + identitySource: "mapping.expression" + identityValidationExpression: "[A-Z]+" resultTtlInSeconds: 100 - }) + } + ) service Weather { version: "2018-03-17" } diff --git a/docs/source/1.0/spec/aws/aws-auth.rst b/docs/source/1.0/spec/aws/aws-auth.rst index f3239ba0b8e..a13c00698f1 100644 --- a/docs/source/1.0/spec/aws/aws-auth.rst +++ b/docs/source/1.0/spec/aws/aws-auth.rst @@ -54,7 +54,7 @@ Trait value @sigv4(name: "foobaz") @restJson1 service FooBaz { - version: "2018-03-17", + version: "2018-03-17" } .. code-tab:: json @@ -109,7 +109,7 @@ operation MUST NOT be used as part of the request signature calculation: @unsignedPayload operation PutThings { - input: PutThingsInput, + input: PutThingsInput output: PutThingsOutput } @@ -182,7 +182,7 @@ Trait value providerArns: ["arn:aws:cognito-idp:us-east-1:123:userpool/123"]) @restJson1 service FooBaz { - version: "2018-03-17", + version: "2018-03-17" } diff --git a/docs/source/1.0/spec/aws/aws-cloudformation.rst b/docs/source/1.0/spec/aws/aws-cloudformation.rst index f64eed1e438..d9f4fccf011 100644 --- a/docs/source/1.0/spec/aws/aws-cloudformation.rst +++ b/docs/source/1.0/spec/aws/aws-cloudformation.rst @@ -74,8 +74,8 @@ resource: @cfnResource resource Foo { identifiers: { - fooId: String, - }, + fooId: String + } } @@ -97,16 +97,16 @@ The following example provides a ``name`` value and one structure shape in the use aws.cloudformation#cfnResource @cfnResource( - name: "Foo", + name: "Foo" additionalSchemas: [AdditionalFooProperties]) resource FooResource { identifiers: { - fooId: String, - }, + fooId: String + } } structure AdditionalFooProperties { - barProperty: String, + barProperty: String } @@ -179,30 +179,30 @@ The following example defines a CloudFormation resource that excludes the @cfnResource resource Foo { identifiers: { - fooId: String, - }, - read: GetFoo, + fooId: String + } + read: GetFoo } @readonly @http(method: "GET", uri: "/foos/{fooId}", code: 200) operation GetFoo { - input: GetFooRequest, - output: GetFooResponse, + input: GetFooRequest + output: GetFooResponse } structure GetFooRequest { @httpLabel @required - fooId: String, + fooId: String } structure GetFooResponse { - fooId: String, + fooId: String @httpResponseCode @cfnExcludeProperty - responseCode: Integer, + responseCode: Integer } @@ -240,62 +240,62 @@ Given the following model without mutability traits applied, @cfnResource resource Foo { identifiers: { - fooId: String, - }, - create: CreateFoo, - read: GetFoo, - update: UpdateFoo, + fooId: String + } + create: CreateFoo + read: GetFoo + update: UpdateFoo } operation CreateFoo { - input: CreateFooRequest, - output: CreateFooResponse, + input: CreateFooRequest + output: CreateFooResponse } structure CreateFooRequest { - createProperty: ComplexProperty, - mutableProperty: ComplexProperty, - writeProperty: ComplexProperty, - createWriteProperty: ComplexProperty, + createProperty: ComplexProperty + mutableProperty: ComplexProperty + writeProperty: ComplexProperty + createWriteProperty: ComplexProperty } structure CreateFooResponse { - fooId: String, + fooId: String } @readonly operation GetFoo { - input: GetFooRequest, - output: GetFooResponse, + input: GetFooRequest + output: GetFooResponse } structure GetFooRequest { @required - fooId: String, + fooId: String } structure GetFooResponse { - fooId: String, - createProperty: ComplexProperty, - mutableProperty: ComplexProperty, - readProperty: ComplexProperty, + fooId: String + createProperty: ComplexProperty + mutableProperty: ComplexProperty + readProperty: ComplexProperty } @idempotent operation UpdateFoo { - input: UpdateFooRequest, + input: UpdateFooRequest } structure UpdateFooRequest { @required - fooId: String, + fooId: String - mutableProperty: ComplexProperty, - writeProperty: ComplexProperty, + mutableProperty: ComplexProperty + writeProperty: ComplexProperty } structure ComplexProperty { - anotherProperty: String, + anotherProperty: String } The computed resource property mutabilities are: @@ -399,28 +399,28 @@ and ``barProperty`` properties as fully mutable: @cfnResource(additionalSchemas: [FooProperties]) resource Foo { identifiers: { - fooId: String, - }, - create: CreateFoo, + fooId: String + } + create: CreateFoo } operation CreateFoo { - input: CreateFooRequest, - output: CreateFooResponse, + input: CreateFooRequest + output: CreateFooResponse } structure CreateFooRequest { @cfnMutability("full") - tags: TagList, + tags: TagList } structure CreateFooResponse { - fooId: String, + fooId: String } structure FooProperties { @cfnMutability("full") - barProperty: String, + barProperty: String } @@ -439,13 +439,13 @@ The following example defines a CloudFormation resource that marks the @cfnResource(additionalSchemas: [FooProperties]) resource Foo { identifiers: { - fooId: String, - }, + fooId: String + } } structure FooProperties { @cfnMutability("create-and-read") - immutableSetting: Boolean, + immutableSetting: Boolean } @@ -464,15 +464,15 @@ The following example defines a CloudFormation resource that marks the @cfnResource(additionalSchemas: [FooProperties]) resource Foo { identifiers: { - fooId: String, - }, - read: GetFoo, + fooId: String + } + read: GetFoo } @readonly operation GetFoo { - input: GetFooRequest, - output: GetFooResponse, + input: GetFooRequest + output: GetFooResponse } structure GetFooRequest { @@ -482,12 +482,12 @@ The following example defines a CloudFormation resource that marks the structure GetFooResponse { @cfnMutability("read") - updatedAt: Timestamp, + updatedAt: Timestamp } structure FooProperties { @cfnMutability("read") - createdAt: Timestamp, + createdAt: Timestamp } @@ -506,28 +506,28 @@ derivable ``secret`` and ``password`` properties as write only: @cfnResource(additionalSchemas: [FooProperties]) resource Foo { identifiers: { - fooId: String, - }, - create: CreateFoo, + fooId: String + } + create: CreateFoo } operation CreateFoo { - input: CreateFooRequest, - output: CreateFooResponse, + input: CreateFooRequest + output: CreateFooResponse } structure CreateFooRequest { @cfnMutability("write") - secret: String, + secret: String } structure CreateFooResponse { - fooId: String, + fooId: String } structure FooProperties { @cfnMutability("write") - password: String, + password: String } @@ -560,10 +560,10 @@ Given the following structure definition: use aws.cloudformation#cfnName structure AdditionalFooProperties { - bar: String, + bar: String @cfnName("Tags") - tagList: TagList, + tagList: TagList } the following property names are derived from it: @@ -618,22 +618,22 @@ The following example defines a CloudFormation resource that has the @cfnResource resource Foo { identifiers: { - fooId: String, - }, - read: GetFoo, + fooId: String + } + read: GetFoo } @readonly operation GetFoo { - input: GetFooRequest, + input: GetFooRequest } structure GetFooRequest { @required - fooId: String, + fooId: String @cfnAdditionalIdentifier - fooAlias: String, + fooAlias: String } @@ -662,106 +662,106 @@ Given the following model, @cfnResource(additionalSchemas: [FooProperties]) resource Foo { identifiers: { - fooId: String, - }, - create: CreateFoo, - read: GetFoo, - update: UpdateFoo, + fooId: String + } + create: CreateFoo + read: GetFoo + update: UpdateFoo } @http(method: "POST", uri: "/foos", code: 200) operation CreateFoo { - input: CreateFooRequest, - output: CreateFooResponse, + input: CreateFooRequest + output: CreateFooResponse } structure CreateFooRequest { @cfnMutability("full") - tags: TagList, + tags: TagList @cfnMutability("write") - secret: String, + secret: String - fooAlias: String, + fooAlias: String - createProperty: ComplexProperty, - mutableProperty: ComplexProperty, - writeProperty: ComplexProperty, - createWriteProperty: ComplexProperty, + createProperty: ComplexProperty + mutableProperty: ComplexProperty + writeProperty: ComplexProperty + createWriteProperty: ComplexProperty } structure CreateFooResponse { - fooId: String, + fooId: String } @readonly @http(method: "GET", uri: "/foos/{fooId}", code: 200) operation GetFoo { - input: GetFooRequest, - output: GetFooResponse, + input: GetFooRequest + output: GetFooResponse } structure GetFooRequest { @httpLabel @required - fooId: String, + fooId: String @httpQuery("fooAlias") @cfnAdditionalIdentifier - fooAlias: String, + fooAlias: String } structure GetFooResponse { - fooId: String, + fooId: String @httpResponseCode @cfnExcludeProperty - responseCode: Integer, + responseCode: Integer @cfnMutability("read") - updatedAt: Timestamp, + updatedAt: Timestamp - fooAlias: String, - createProperty: ComplexProperty, - mutableProperty: ComplexProperty, - readProperty: ComplexProperty, + fooAlias: String + createProperty: ComplexProperty + mutableProperty: ComplexProperty + readProperty: ComplexProperty } @idempotent @http(method: "PUT", uri: "/foos/{fooId}", code: 200) operation UpdateFoo { - input: UpdateFooRequest, + input: UpdateFooRequest } structure UpdateFooRequest { @httpLabel @required - fooId: String, + fooId: String - fooAlias: String, - mutableProperty: ComplexProperty, - writeProperty: ComplexProperty, + fooAlias: String + mutableProperty: ComplexProperty + writeProperty: ComplexProperty } structure FooProperties { - addedProperty: String, + addedProperty: String @cfnMutability("full") - barProperty: String, + barProperty: String @cfnName("Immutable") @cfnMutability("create-and-read") - immutableSetting: Boolean, + immutableSetting: Boolean @cfnMutability("read") - createdAt: Timestamp, + createdAt: Timestamp @cfnMutability("write") - password: String, + password: String } structure ComplexProperty { - anotherProperty: String, + anotherProperty: String } list TagList { diff --git a/docs/source/1.0/spec/aws/aws-core.rst b/docs/source/1.0/spec/aws/aws-core.rst index 8d0cdc4551a..283b522dcfb 100644 --- a/docs/source/1.0/spec/aws/aws-core.rst +++ b/docs/source/1.0/spec/aws/aws-core.rst @@ -46,7 +46,7 @@ The following example defines an AWS service that uses the default values of @service(sdkId: "Some Value") service FooBaz { - version: "2018-03-17", + version: "2018-03-17" } .. code-tab:: json @@ -78,14 +78,14 @@ The following example provides explicit values for all properties: use aws.api#service @service( - sdkId: "Some Value", - cloudFormationName: "FooBaz", - arnNamespace: "myservice", - cloudTrailEventSource: "myservice.amazon.aws", + sdkId: "Some Value" + cloudFormationName: "FooBaz" + arnNamespace: "myservice" + cloudTrailEventSource: "myservice.amazon.aws" endpointPrefix: "my-endpoint" ) service FooBaz { - version: "2018-03-17", + version: "2018-03-17" } .. code-tab:: json @@ -382,13 +382,13 @@ For example, given the following service: @service(sdkId: "Some Value") service FooBaz { - version: "2018-03-17", - resources: [MyResource], + version: "2018-03-17" + resources: [MyResource] } @arn(template: "myresource/{myId}") resource MyResource { - identifiers: {myId: MyResourceId}, + identifiers: {myId: MyResourceId} } .. code-tab:: json @@ -550,8 +550,8 @@ referenced resource. use aws.api#arnReference @arnReference( - type: "AWS::SomeService::SomeResource", - service: com.foo#SomeService, + type: "AWS::SomeService::SomeResource" + service: com.foo#SomeService resource: com.foo#SomeResource) string SomeResourceId @@ -630,12 +630,12 @@ structure, union, or collection unless overridden. @data("permissions") structure MyStructure { - name: String, + name: String @data("content") - content: String, + content: String - tags: TagList, + tags: TagList } @data("tagging") @@ -765,7 +765,7 @@ plane unless an operation or resource is marked with the @controlPlane operation PutThings { - input: PutThingsInput, + input: PutThingsInput output: PutThingsOutput } @@ -819,7 +819,7 @@ plane unless an operation or resource is marked with the @dataPlane operation PutThings { - input: PutThingsInput, + input: PutThingsInput output: PutThingsOutput } @@ -962,17 +962,17 @@ using an ``clientEndpointDiscoveryId``. .. code-tab:: smithy @aws.api#clientEndpointDiscovery( - operation: DescribeEndpoints, - error: InvalidEndpointError, + operation: DescribeEndpoints + error: InvalidEndpointError ) service FooService { - version: "2019-09-10", + version: "2019-09-10" operations: [DescribeEndpoints, GetObject] } operation DescribeEndpoints { - input: DescribeEndpointsInput, - output: DescribeEndpointsOutput, + input: DescribeEndpointsInput + output: DescribeEndpointsOutput errors: [InvalidEndpointError] } @@ -981,17 +981,17 @@ using an ``clientEndpointDiscoveryId``. structure InvalidEndpointError {} structure DescribeEndpointsInput { - Operation: String, - Identifiers: Identifiers, + Operation: String + Identifiers: Identifiers } map Identifiers { - key: String, + key: String value: String } structure DescribeEndpointsOutput { - Endpoints: Endpoints, + Endpoints: Endpoints } list Endpoints { @@ -999,24 +999,24 @@ using an ``clientEndpointDiscoveryId``. } structure Endpoint { - Address: String, - CachePeriodInMinutes: Long, + Address: String + CachePeriodInMinutes: Long } @aws.api#clientDiscoveredEndpoint(required: true) operation GetObject { - input: GetObjectInput, + input: GetObjectInput output: GetObjectOutput } structure GetObjectInput { @clientEndpointDiscoveryId @required - Id: String, + Id: String } structure GetObjectOutput { - Object: Blob, + Object: Blob } .. code-tab:: json diff --git a/docs/source/1.0/spec/aws/aws-ec2-query-protocol.rst b/docs/source/1.0/spec/aws/aws-ec2-query-protocol.rst index 3f98ceae8a7..c4f0f6696eb 100644 --- a/docs/source/1.0/spec/aws/aws-ec2-query-protocol.rst +++ b/docs/source/1.0/spec/aws/aws-ec2-query-protocol.rst @@ -239,23 +239,23 @@ For example, given the following: .. code-block:: smithy structure Ec2QueryStructuresInput { - foo: String, + foo: String @ec2QueryName("A") - HasQueryName: String, + HasQueryName: String @ec2QueryName("B") @xmlName("IgnoreMe") - HasQueryAndXmlName: String, + HasQueryAndXmlName: String @xmlName("c") - UsesXmlName: String, + UsesXmlName: String - baz: MyStructure, + baz: MyStructure } structure MyStructure { - temp: String, + temp: String } The ``x-www-form-urlencoded`` serialization is: @@ -281,19 +281,19 @@ For example, given the following: .. code-block:: smithy structure Ec2QueryListsInput { - ListArg: StringList, - ComplexListArg: GreetingList, + ListArg: StringList + ComplexListArg: GreetingList @xmlFlattened - FlattenedListArg: StringList, + FlattenedListArg: StringList - ListArgWithXmlNameMember: ListWithXmlName, + ListArgWithXmlNameMember: ListWithXmlName // Notice that the xmlName on the targeted list member is ignored. @xmlFlattened @ec2QueryName("Hi") @xmlName("IgnoreMe") - FlattenedListArgWithXmlName: ListWithXmlName, + FlattenedListArgWithXmlName: ListWithXmlName } list ListWithXmlName { @@ -310,7 +310,7 @@ For example, given the following: } structure GreetingStruct { - hi: String, + hi: String } The ``x-www-form-urlencoded`` serialization is: diff --git a/docs/source/1.0/spec/aws/aws-iam.rst b/docs/source/1.0/spec/aws/aws-iam.rst index 51a14934c54..398f98b4c18 100644 --- a/docs/source/1.0/spec/aws/aws-iam.rst +++ b/docs/source/1.0/spec/aws/aws-iam.rst @@ -96,14 +96,14 @@ The following example's ``MyResource`` resource has the @service(sdkId: "My Value", arnNamespace: "myservice") @defineConditionKeys("otherservice:Bar": { type: "String" }) service MyService { - version: "2017-02-11", - resources: [MyResource], + version: "2017-02-11" + resources: [MyResource] } @conditionKeys(["otherservice:Bar"]) resource MyResource { - identifiers: {foo: String}, - operations: [MyOperation], + identifiers: {foo: String} + operations: [MyOperation] } @conditionKeys(["aws:region"]) @@ -223,13 +223,13 @@ Each condition key structure supports the following members: @service(sdkId: "My Value", arnNamespace: "myservice") @defineConditionKeys( "otherservice:Bar": { - type: "String", - documentation: "The Bar string", + type: "String" + documentation: "The Bar string" externalDocumentation: "http://example.com" }) service MyService { - version: "2017-02-11", - resources: [MyResource], + version: "2017-02-11" + resources: [MyResource] } .. code-tab:: json @@ -343,16 +343,16 @@ condition key inference disabled. @service(sdkId: "My Value", arnNamespace: "myservice") service MyService { - version: "2017-02-11", - resources: [MyResource], + version: "2017-02-11" + resources: [MyResource] } @disableConditionKeyInference resource MyResource { identifiers: { - foo: String, - bar: String, - }, + foo: String + bar: String + } } .. code-tab:: json @@ -424,13 +424,13 @@ operation for it to complete successfully. @service(sdkId: "My Value", arnNamespace: "myservice") service MyService { - version: "2017-02-11", - resources: [MyResource], + version: "2017-02-11" + resources: [MyResource] } resource MyResource { - identifiers: {foo: String}, - operations: [MyOperation], + identifiers: {foo: String} + operations: [MyOperation] } @requiredActions(["otherservice:OtherOperation"]) @@ -514,15 +514,15 @@ Given the following model, @service(sdkId: "My Value", arnNamespace: "myservice") @defineConditionKeys("otherservice:Bar": { type: "String" }) service MyService { - version: "2017-02-11", - resources: [MyResource], + version: "2017-02-11" + resources: [MyResource] } @conditionKeys(["otherservice:Bar"]) resource MyResource { - identifiers: {foo: String}, - operations: [MyOperation], - resources: [MyInnerResource], + identifiers: {foo: String} + operations: [MyOperation] + resources: [MyInnerResource] } resource MyInnerResource { diff --git a/docs/source/1.0/spec/aws/aws-query-protocol.rst b/docs/source/1.0/spec/aws/aws-query-protocol.rst index dfd5305e704..48c32f9e269 100644 --- a/docs/source/1.0/spec/aws/aws-query-protocol.rst +++ b/docs/source/1.0/spec/aws/aws-query-protocol.rst @@ -156,16 +156,16 @@ For example, given the following: .. code-block:: smithy structure QueryStructuresInput { - foo: String, + foo: String @xmlName("Custom") - bar: String, + bar: String - baz: MyStructure, + baz: MyStructure } structure MyStructure { - temp: String, + temp: String } The ``x-www-form-urlencoded`` serialization is: @@ -189,18 +189,18 @@ For example, given the following: .. code-block:: smithy structure QueryListsInput { - ListArg: StringList, - ComplexListArg: GreetingList, + ListArg: StringList + ComplexListArg: GreetingList @xmlFlattened - FlattenedListArg: StringList, + FlattenedListArg: StringList - ListArgWithXmlNameMember: ListWithXmlName, + ListArgWithXmlNameMember: ListWithXmlName // Notice that the xmlName on the targeted list member is ignored. @xmlFlattened @xmlName("Hi") - FlattenedListArgWithXmlName: ListWithXmlName, + FlattenedListArgWithXmlName: ListWithXmlName } list ListWithXmlName { @@ -217,7 +217,7 @@ For example, given the following: } structure GreetingStruct { - hi: String, + hi: String } The ``x-www-form-urlencoded`` serialization is: @@ -249,36 +249,36 @@ For example, given the following: .. code-block:: smithy structure QueryMapsInput { - MapArg: StringMap, + MapArg: StringMap @xmlName("reNamed") - RenamedMapArg: StringMap, + RenamedMapArg: StringMap - ComplexMapArg: ComplexMap, + ComplexMapArg: ComplexMap - MapWithXmlMemberName: MapWithXmlName, + MapWithXmlMemberName: MapWithXmlName } map StringMap { - key: String, + key: String value: String } map ComplexMap { - key: String, - value: GreetingStruct, + key: String + value: GreetingStruct } map MapWithXmlName { @xmlName("K") - key: String, + key: String @xmlName("V") value: String } structure GreetingStruct { - hi: String, + hi: String } The ``x-www-form-urlencoded`` serialization is: diff --git a/docs/source/1.0/spec/core/auth-traits.rst b/docs/source/1.0/spec/core/auth-traits.rst index a953a61408b..3c91dd675df 100644 --- a/docs/source/1.0/spec/core/auth-traits.rst +++ b/docs/source/1.0/spec/core/auth-traits.rst @@ -62,7 +62,7 @@ and the hypothetical ``fooExample`` authentication scheme. @fooExample @httpBasicAuth service WeatherService { - version: "2017-02-11", + version: "2017-02-11" } .. code-tab:: json @@ -100,7 +100,7 @@ can also support configuration settings. @authDefinition @trait(selector: "service") structure algorithmAuth { - algorithm: AlgorithmAuthAlgorithm, + algorithm: AlgorithmAuthAlgorithm } @private @@ -109,7 +109,7 @@ can also support configuration settings. @algorithmAuth(algorithm: "SHA-2") service WeatherService { - version: "2017-02-11", + version: "2017-02-11" } @@ -131,7 +131,7 @@ Value type @httpBasicAuth service WeatherService { - version: "2017-02-11", + version: "2017-02-11" } @@ -153,7 +153,7 @@ Value type @httpDigestAuth service WeatherService { - version: "2017-02-11", + version: "2017-02-11" } @@ -175,7 +175,7 @@ Value type @httpBearerAuth service WeatherService { - version: "2017-02-11", + version: "2017-02-11" } @@ -219,7 +219,7 @@ HTTP header: @httpApiKeyAuth(name: "X-Api-Key", in: "header") service WeatherService { - version: "2017-02-11", + version: "2017-02-11" } @@ -244,7 +244,7 @@ and bound to the service is an operation that supports unauthenticated access. @httpDigestAuth service WeatherService { - version: "2017-02-11", + version: "2017-02-11" operations: [PingServer] } @@ -306,7 +306,7 @@ The following example defines two operations: @httpDigestAuth @auth([httpBasicAuth]) service AuthenticatedService { - version: "2017-02-11", + version: "2017-02-11" operations: [OperationA, OperationB] } diff --git a/docs/source/1.0/spec/core/behavior-traits.rst b/docs/source/1.0/spec/core/behavior-traits.rst index fd876c6932f..22cf21ac898 100644 --- a/docs/source/1.0/spec/core/behavior-traits.rst +++ b/docs/source/1.0/spec/core/behavior-traits.rst @@ -51,7 +51,7 @@ member if and only if the member is not explicitly provided. structure AllocateWidgetInput { @idempotencyToken - clientToken: String, + clientToken: String } @@ -78,7 +78,7 @@ Conflicts with @idempotent operation DeleteSomething { - input: DeleteSomethingInput, + input: DeleteSomethingInput output: DeleteSomethingOutput } @@ -109,7 +109,7 @@ Conflicts with @readonly operation GetSomething { - input: GetSomethingInput, + input: GetSomethingInput output: GetSomethingOutput } @@ -244,20 +244,20 @@ explicitly on the operation. @paginated(inputToken: "nextToken", outputToken: "nextToken", pageSize: "maxResults", items: "foos") operation GetFoos { - input: GetFoosInput, + input: GetFoosInput output: GetFoosOutput } structure GetFoosInput { - maxResults: Integer, + maxResults: Integer nextToken: String } structure GetFoosOutput { - nextToken: String, + nextToken: String @required - foos: StringList, + foos: StringList } list StringList { @@ -338,13 +338,13 @@ settings from a service. @paginated(inputToken: "nextToken", outputToken: "nextToken", pageSize: "maxResults") service Example { - version: "2019-06-27", - operations: [GetFoos], + version: "2019-06-27" + operations: [GetFoos] } @readonly @paginated(items: "foos") operation GetFoos { - input: GetFoosInput, + input: GetFoosInput output: GetFoosOutput } @@ -405,12 +405,12 @@ wrapper where the output token and items are referenced by paths. @paginated(inputToken: "nextToken", outputToken: "result.nextToken", pageSize: "maxResults", items: "result.foos") operation GetFoos { - input: GetFoosInput, + input: GetFoosInput output: GetFoosOutput } structure GetFoosInput { - maxResults: Integer, + maxResults: Integer nextToken: String } @@ -420,10 +420,10 @@ wrapper where the output token and items are referenced by paths. } structure ResultWrapper { - nextToken: String, + nextToken: String @required - foos: StringList, + foos: StringList } list StringList { @@ -652,6 +652,6 @@ See @httpChecksumRequired operation PutSomething { - input: PutSomethingInput, + input: PutSomethingInput output: PutSomethingOutput } diff --git a/docs/source/1.0/spec/core/constraint-traits.rst b/docs/source/1.0/spec/core/constraint-traits.rst index 1f31182fac8..fb170e48a39 100644 --- a/docs/source/1.0/spec/core/constraint-traits.rst +++ b/docs/source/1.0/spec/core/constraint-traits.rst @@ -93,28 +93,28 @@ The following example defines an enum of valid string values for ``MyString``. @enum([ { - value: "t2.nano", - name: "T2_NANO", + value: "t2.nano" + name: "T2_NANO" documentation: """ T2 instances are Burstable Performance Instances that provide a baseline level of CPU performance with the ability to burst above the - baseline.""", + baseline.""" tags: ["ebsOnly"] - }, + } { - value: "t2.micro", - name: "T2_MICRO", + value: "t2.micro" + name: "T2_MICRO" documentation: """ T2 instances are Burstable Performance Instances that provide a baseline level of CPU performance with the ability to burst above the - baseline.""", + baseline.""" tags: ["ebsOnly"] - }, + } { - value: "m256.mega", - name: "M256_MEGA", + value: "m256.mega" + name: "M256_MEGA" deprecated: true } ]) @@ -548,7 +548,7 @@ in a response. structure MyStructure { @required - foo: FooString, + foo: FooString } .. code-tab:: json @@ -596,7 +596,7 @@ Value type @uniqueItems list MyList { - member: String, + member: String } .. code-tab:: json diff --git a/docs/source/1.0/spec/core/documentation-traits.rst b/docs/source/1.0/spec/core/documentation-traits.rst index 2266b5f2a68..0a4ca0c576e 100644 --- a/docs/source/1.0/spec/core/documentation-traits.rst +++ b/docs/source/1.0/spec/core/documentation-traits.rst @@ -115,11 +115,11 @@ For example, given the following model, structure Foo { @documentation("Member documentation") - baz: Baz, + baz: Baz - bar: Baz, + bar: Baz - qux: String, + qux: String } @documentation("Shape documentation") @@ -211,29 +211,29 @@ These values use the same semantics and format as @readonly operation MyOperation { - input: MyOperationInput, + input: MyOperationInput output: MyOperationOutput } apply MyOperation @examples([ { - title: "Invoke MyOperation", + title: "Invoke MyOperation" input: { - tags: ["foo", "baz", "bar"], + tags: ["foo", "baz", "bar"] }, output: { - status: "PENDING", + status: "PENDING" } - }, + } { - title: "Another example for MyOperation", + title: "Another example for MyOperation" input: { - foo: "baz", - }, + foo: "baz" + } output: { - status: "PENDING", + status: "PENDING" } - }, + } ]) @@ -256,11 +256,11 @@ Value type .. code-tab:: smithy @externalDocumentation( - "Homepage": "https://www.example.com/", - "API Reference": "https://www.example.com/api-ref", + "Homepage": "https://www.example.com/" + "API Reference": "https://www.example.com/api-ref" ) service MyService { - version: "2006-03-01", + version: "2006-03-01" } @@ -289,10 +289,10 @@ filtered version of the model. .. code-tab:: smithy structure MyStructure { - foo: String, + foo: String @internal - bar: String, + bar: String } @@ -331,10 +331,10 @@ Conflicts with structure PutContentsInput { @required - contents: String, + contents: String @recommended(reason: "Validation will reject contents if they are invalid.") - validateContents: Boolean, + validateContents: Boolean } @@ -432,7 +432,7 @@ Value type @title("ACME Simple Image Service") service MySimpleImageService { - version: "2006-03-01", + version: "2006-03-01" } diff --git a/docs/source/1.0/spec/core/endpoint-traits.rst b/docs/source/1.0/spec/core/endpoint-traits.rst index e614b1ed2a1..0151489c9c9 100644 --- a/docs/source/1.0/spec/core/endpoint-traits.rst +++ b/docs/source/1.0/spec/core/endpoint-traits.rst @@ -55,7 +55,7 @@ The following example defines an operation that uses a custom endpoint: @readonly @endpoint(hostPrefix: "{foo}.data.") operation GetStatus { - input: GetStatusInput, + input: GetStatusInput output: GetStatusOutput } @@ -121,7 +121,7 @@ Given the following operation, @readonly @endpoint(hostPrefix: "{foo}.data.") operation GetStatus { - input: GetStatusInput, + input: GetStatusInput output: GetStatusOutput } @@ -186,7 +186,7 @@ Given the following operation, @readonly @endpoint(hostPrefix: "{foo}-{bar}.data.") operation GetStatus { - input: GetStatusInput, + input: GetStatusInput output: GetStatusOutput } @@ -261,7 +261,7 @@ invalid because the ``{foo}`` and ``{bar}`` labels are adjacent: @readonly @endpoint(hostPrefix: "{foo}{bar}.data.") operation GetStatus { - input: GetStatusInput, + input: GetStatusInput output: GetStatusOutput } @@ -322,7 +322,7 @@ Given the following operation, @endpoint(hostPrefix: "{foo}.data.") @http(method: "GET", uri: "/status") operation GetStatus { - input: GetStatusInput, + input: GetStatusInput output: GetStatusOutput } @@ -414,7 +414,7 @@ to an operation marked with the :ref:`endpoint-trait` will be ignored. @readonly @endpoint(hostPrefix: "{foo}.data") operation GetStatus { - input: GetStatusInput, + input: GetStatusInput output: GetStatusOutput } diff --git a/docs/source/1.0/spec/core/http-traits.rst b/docs/source/1.0/spec/core/http-traits.rst index 3700d3e0d74..d1347c7d0c0 100644 --- a/docs/source/1.0/spec/core/http-traits.rst +++ b/docs/source/1.0/spec/core/http-traits.rst @@ -69,26 +69,26 @@ The following example defines an operation that uses HTTP bindings: // Sent in the URI label named "key". @required @httpLabel - key: ObjectKey, + key: ObjectKey // Sent in the URI label named "bucketName". @required @httpLabel - bucketName: String, + bucketName: String // Sent in the X-Foo header @httpHeader("X-Foo") - foo: String, + foo: String // Sent in the query string as paramName @httpQuery("paramName") - someValue: String, + someValue: String // Sent in the body - data: MyBlob, + data: MyBlob // Sent in the body - additional: String, + additional: String } @@ -627,7 +627,7 @@ The following example defines an operation that send an HTTP label named @readonly @http(method: "GET", uri: "/{foo}") operation GetStatus { - input: GetStatusInput, + input: GetStatusInput output: GetStatusOutput } @@ -713,16 +713,16 @@ data in a response: @readonly @http(method: "GET", uri: "/random-binary-data") operation GetRandomBinaryData { - output: GetRandomBinaryDataOutput, + output: GetRandomBinaryDataOutput } structure GetRandomBinaryDataOutput { @required @httpHeader("Content-Type") - contentType: String, + contentType: String @httpPayload - content: Blob, + content: Blob } .. _http-protocol-document-payloads: @@ -805,7 +805,7 @@ Given the following Smithy model: } map StringMap { - key: String, + key: String value: String } @@ -875,19 +875,19 @@ request: @readonly @http(method: "GET", uri: "/things") operation ListThings { - input: ListThingsInput, + input: ListThingsInput output: ListThingsOutput, // omitted for brevity } structure ListThingsInput { @httpQuery("color") - color: String, + color: String @httpQuery("shape") - shape: String, + shape: String @httpQuery("size") - size: Integer, + size: Integer } .. rubric:: Serialization rules @@ -968,17 +968,17 @@ target input map as query string parameters in an HTTP request: @readonly @http(method: "GET", uri: "/things") operation ListThings { - input: ListThingsInput, + input: ListThingsInput output: ListThingsOutput, // omitted for brevity } structure ListThingsInput { @httpQueryParams() - myParams: MapOfStrings, + myParams: MapOfStrings } map MapOfStrings { - key: String, + key: String value: String } @@ -1167,16 +1167,16 @@ and HTTP bindings: structure PublishMessagesInput { @httpPayload - messages: MessageStream, + messages: MessageStream } @streaming union MessageStream { - message: Message, + message: Message } structure Message { - message: String, + message: String } .. code-tab:: json @@ -1245,11 +1245,11 @@ marked with the ``httpPayload`` trait: @streaming union MessageStream { - message: Message, + message: Message } structure Message { - message: String, + message: String } diff --git a/docs/source/1.0/spec/core/idl.rst b/docs/source/1.0/spec/core/idl.rst index ea4fca944b2..6009f1ecd48 100644 --- a/docs/source/1.0/spec/core/idl.rst +++ b/docs/source/1.0/spec/core/idl.rst @@ -77,8 +77,12 @@ The following example defines a model file with each section: Lexical notes ------------- -Smithy models MUST be encoded using UTF-8 and SHOULD use Unix style -line endings (``\n``). The Smithy ABNF is whitespace sensitive. +* Smithy models MUST be encoded using UTF-8 and SHOULD use Unix style + line endings (``\n``). +* The Smithy ABNF is whitespace sensitive. +* Except for within strings, commas in the Smithy IDL are considered + whitespace. Commas can be used anywhere where they make the model + easier to read (for example, in complex traits defined on a single line). .. _smithy-idl-abnf: @@ -95,7 +99,7 @@ The Smithy IDL is defined by the following ABNF: .. rubric:: Whitespace .. productionlist:: smithy - ws :*(`sp` / `newline` / `comment`) ; whitespace + ws :*(`sp` / `newline` / `comment` / ",") ; whitespace sp :*(%x20 / %x09) ; " " and \t br :`sp` (`comment` / `newline`) `sp` ; break newline :%x0A / %x0D.0A ; \n and \r\n @@ -112,13 +116,13 @@ The Smithy IDL is defined by the following ABNF: .. productionlist:: smithy control_section :*(`control_statement`) - control_statement :"$" `ws` `node_object_key` `ws` ":" `ws` `node_value` `br` + control_statement :"$" `ws` `node_object_key` `ws` ":" `ws` `node_value` `ws` .. rubric:: Metadata .. productionlist:: smithy metadata_section :*(`metadata_statement`) - metadata_statement :"metadata" `ws` `node_object_key` `ws` "=" `ws` `node_value` `br` + metadata_statement :"metadata" `ws` `node_object_key` `ws` "=" `ws` `node_value` `ws` .. rubric:: Node values @@ -128,18 +132,8 @@ The Smithy IDL is defined by the following ABNF: :/ `number` :/ `node_keywords` :/ `node_string_value` - node_array :`empty_node_array` / `populated_node_array` - empty_node_array :"[" `ws` "]" - populated_node_array:"[" `ws` `node_value` `ws` - : *(`comma` `node_value` `ws`) - : `trailing_comma` "]" - trailing_comma :[`comma`] - comma :"," `ws` - node_object :`empty_node_object` / `populated_node_object` - empty_node_object :"{" `ws` "}" - populated_node_object:"{" `ws` `node_object_kvp` `ws` - : *(`comma` `node_object_kvp` `ws`) - : `trailing_comma` "}" + node_array :"[" `ws` *(`node_value` `ws`) "]" + node_object :"{" `ws` *(`node_object_kvp` `ws`) "}" node_object_kvp :`node_object_key` `ws` ":" `ws` `node_value` node_object_key :`quoted_text` / `identifier` number :[`minus`] `int` [`frac`] [`exp`] @@ -172,11 +166,11 @@ The Smithy IDL is defined by the following ABNF: .. productionlist:: smithy shape_section :[`namespace_statement` [`use_section`] [`shape_statements`]] - namespace_statement :"namespace" `ws` `namespace` `br` + namespace_statement :"namespace" `ws` `namespace` `ws` use_section :*(`use_statement`) - use_statement :"use" `ws` `absolute_root_shape_id` `br` + use_statement :"use" `ws` `absolute_root_shape_id` `ws` shape_statements :*(`shape_statement` / `apply_statement`) - shape_statement :`trait_statements` `shape_body` `br` + shape_statement :`trait_statements` `shape_body` `ws` shape_body :`simple_shape_statement` :/ `list_statement` :/ `set_statement` @@ -191,11 +185,8 @@ The Smithy IDL is defined by the following ABNF: :/ "byte" / "short" / "integer" / "long" :/ "float" / "double" / "bigInteger" :/ "bigDecimal" / "timestamp" - shape_members :`empty_shape_members` / `populated_shape_members` - empty_shape_members :"{" `ws` "}" - populated_shape_members :"{" `ws` `shape_member_kvp` - : *(`comma` `shape_member_kvp` `ws`) `trailing_comma` "}" - shape_member_kvp :`trait_statements` `identifier` `ws` ":" `ws` `shape_id` + shape_members :"{" `ws` *(`shape_member_kvp` `ws`) "}" + shape_member_kvp :`trait_statements` `identifier` `ws` ":" `ws` `shape_id` list_statement :"list" `ws` `identifier` `ws` `shape_members` set_statement :"set" `ws` `identifier` `ws` `shape_members` map_statement :"map" `ws` `identifier` `ws` `shape_members` @@ -212,9 +203,9 @@ The Smithy IDL is defined by the following ABNF: trait :"@" `shape_id` [`trait_body`] trait_body :"(" `ws` `trait_body_value` `ws` ")" trait_body_value :`trait_structure` / `node_value` - trait_structure :`trait_structure_kvp` *(`ws` `comma` `trait_structure_kvp`) + trait_structure :`trait_structure_kvp` *(`ws` `trait_structure_kvp`) trait_structure_kvp :`node_object_key` `ws` ":" `ws` `node_value` - apply_statement :"apply" `ws` `shape_id` `ws` `trait` `br` + apply_statement :"apply" `ws` `shape_id` `ws` `trait` `ws` .. rubric:: Shape ID diff --git a/docs/source/1.0/spec/core/model-validation.rst b/docs/source/1.0/spec/core/model-validation.rst index 76cf81c6945..7f0b10a117b 100644 --- a/docs/source/1.0/spec/core/model-validation.rst +++ b/docs/source/1.0/spec/core/model-validation.rst @@ -106,16 +106,16 @@ The following Smithy document applies a custom validator named "SomeValidator": metadata validators = [ { // The name of the validator. - name: "SomeValidator", + name: "SomeValidator" // Uses a custom event ID for each validation event emitted. - id: "CustomEventId", + id: "CustomEventId" // Uses a custom message that also includes the default message. - message: "My custom message name. {super}", + message: "My custom message name. {super}" // Applies the rule only to the following namespaces. - namespaces: ["foo.baz", "bar.qux"], + namespaces: ["foo.baz", "bar.qux"] // The following properties are specific to the validator. configuration: { - "someProperty": "foo", + "someProperty": "foo" } } ] @@ -253,8 +253,8 @@ in the ``foo.baz`` namespace with an ID of ``UnreferencedShape``: metadata suppressions = [ { - id: "UnreferencedShape", - namespace: "foo.baz", + id: "UnreferencedShape" + namespace: "foo.baz" reason: "This is a test namespace." } ] @@ -268,7 +268,7 @@ ID of ``OverlyBroadValidator``: metadata suppressions = [ { - id: "OverlyBroadValidator", + id: "OverlyBroadValidator" namespace: "*" } ] @@ -335,8 +335,8 @@ following constraints: $version: "1.0" metadata validators = [{ - name: "EmitEachSelector", - id: "MissingDocumentation", + name: "EmitEachSelector" + id: "MissingDocumentation" message: "This shape is missing documentation" configuration: { selector: """ @@ -357,17 +357,17 @@ input/output that has a shape name that does not case-insensitively end with metadata validators = [ { - name: "EmitEachSelector", - id: "OperationInputName", - message: "This shape is referenced as input but the name does not end with 'Input'", + name: "EmitEachSelector" + id: "OperationInputName" + message: "This shape is referenced as input but the name does not end with 'Input'" configuration: { selector: "operation -[input]-> :not([id|name$=Input i])" } - }, + } { - name: "EmitEachSelector", - id: "OperationOutputName", - message: "This shape is referenced as output but the name does not end with 'Output'", + name: "EmitEachSelector" + id: "OperationOutputName" + message: "This shape is referenced as output but the name does not end with 'Output'" configuration: { selector: "operation -[output]-> :not([id|name$=Output i])" } @@ -384,17 +384,17 @@ as lifecycle 'read' or 'delete' that has a shape name that does not start with metadata validators = [ { - name: "EmitEachSelector", - id: "LifecycleGetName", - message: "Lifecycle 'read' operation shape names should start with 'Get'", + name: "EmitEachSelector" + id: "LifecycleGetName" + message: "Lifecycle 'read' operation shape names should start with 'Get'" configuration: { selector: "operation [read]-> :not([id|name^=Get i])" } - }, + } { - name: "EmitEachSelector", - id: "LifecycleDeleteName", - message: "Lifecycle 'delete' operation shape names should start with 'Delete'", + name: "EmitEachSelector" + id: "LifecycleDeleteName" + message: "Lifecycle 'delete' operation shape names should start with 'Delete'" configuration: { selector: "operation -[delete]-> :not([id|name^=Delete i])" } @@ -420,11 +420,11 @@ Consider the following model: metadata validators = [ { - name: "EmitEachSelector", - id: "DocumentedString", + name: "EmitEachSelector" + id: "DocumentedString" configuration: { // matches all shapes - selector: "*", + selector: "*" // Only emitted for shapes with the documentation // trait, and each event points to where the // trait is defined. @@ -471,9 +471,9 @@ Consider the following model: metadata validators = [ { - name: "EmitEachSelector", + name: "EmitEachSelector" configuration: { - selector: "[trait|documentation]", + selector: "[trait|documentation]" messageTemplate: """ This shape has a name of @{id|name} and a @@documentation \ trait of "@{trait|documentation}".""" @@ -509,12 +509,12 @@ to make message templates more descriptive. Consider the following example: metadata validators = [ { - name: "EmitEachSelector", - id: "UnstableTrait", + name: "EmitEachSelector" + id: "UnstableTrait" configuration: { selector: """ $matches(-[trait]-> [trait|unstable]) - ${matches}""", + ${matches}""" messageTemplate: "This shape applies traits(s) that are unstable: @{var|matches|id}" } } @@ -641,12 +641,12 @@ traits. $version: "1.0" metadata validators = [{ - name: "EmitNoneSelector", - id: "MissingConstraintTraits", + name: "EmitNoneSelector" + id: "MissingConstraintTraits" message: """ No instances of the enum, pattern, length, or range trait - could be found. Did you forget to apply these traits?""", + could be found. Did you forget to apply these traits?""" configuration: { - selector: ":is([trait|enum], [trait|pattern], [trait|length], [trait|range])", + selector: ":is([trait|enum], [trait|pattern], [trait|length], [trait|range])" } }] diff --git a/docs/source/1.0/spec/core/model.rst b/docs/source/1.0/spec/core/model.rst index be1bc060039..086e4480018 100644 --- a/docs/source/1.0/spec/core/model.rst +++ b/docs/source/1.0/spec/core/model.rst @@ -849,7 +849,7 @@ The following example defines a map of strings to integers: namespace smithy.example map IntegerMap { - key: String, + key: String value: Integer } @@ -890,7 +890,7 @@ dense. The following example defines a sparse map: @sparse map SparseMap { - key: String, + key: String value: String } @@ -949,10 +949,10 @@ is marked with the :ref:`required-trait`. namespace smithy.example structure MyStructure { - foo: String, + foo: String @required - baz: Integer, + baz: Integer } .. code-tab:: json @@ -1033,12 +1033,12 @@ The following example defines a union shape with several members: namespace smithy.example union MyUnion { - i32: Integer, + i32: Integer - stringA: String, + stringA: String @sensitive - stringB: String, + stringB: String } .. code-tab:: json @@ -1283,8 +1283,8 @@ that do not fit within a resource hierarchy. namespace smithy.example service MyService { - version: "2017-02-11", - operations: [GetServerTime], + version: "2017-02-11" + operations: [GetServerTime] } @readonly @@ -1331,8 +1331,8 @@ shape ID of a resource to the ``resources`` property of a service. namespace smithy.example service MyService { - version: "2017-02-11", - resources: [MyResource], + version: "2017-02-11" + resources: [MyResource] } resource MyResource {} @@ -1418,20 +1418,20 @@ the conflicting shapes. namespace smithy.example service MyService { - version: "2017-02-11", - operations: [GetSomething], + version: "2017-02-11" + operations: [GetSomething] rename: { "foo.example#Widget": "FooWidget" } } operation GetSomething { - output: GetSomethingOutput, + output: GetSomethingOutput } structure GetSomethingOutput { - widget1: Widget, - fooWidget: foo.example#Widget, + widget1: Widget + fooWidget: foo.example#Widget } structure Widget {} @@ -1533,8 +1533,8 @@ can potentially return the ``NotFound`` or ``BadRequest`` namespace smithy.example operation MyOperation { - input: Input, - output: Output, + input: Input + output: Output errors: [NotFound, BadRequest] } @@ -1655,9 +1655,7 @@ single identifier named ``forecastId`` that targets the ``ForecastId`` shape: namespace smithy.example resource Forecast { - identifiers: { - forecastId: ForecastId - } + identifiers: { forecastId: ForecastId } } string ForecastId @@ -1701,23 +1699,23 @@ For example, given the following model, resource ResourceA { identifiers: { a: String - }, - resources: [ResourceB], + } + resources: [ResourceB] } resource ResourceB { identifiers: { - a: String, - b: String, - }, - resources: [ResourceC], + a: String + b: String + } + resources: [ResourceC] } resource ResourceC { identifiers: { - a: String, - b: String, - c: String, + a: String + b: String + c: String } } @@ -1785,25 +1783,25 @@ define an ``identifiers`` property that is compatible with their parents: resource ResourceA { identifiers: { - a: String, - b: String, - }, - resources: [Invalid1, Invalid2], + a: String + b: String + } + resources: [Invalid1, Invalid2] } resource Invalid1 { // Invalid: missing "a". identifiers: { - b: String, - }, + b: String + } } resource Invalid2 { identifiers: { - a: String, + a: String // Invalid: does not target the same shape. - b: SomeOtherString, - }, + b: SomeOtherString + } } .. code-tab:: json @@ -1905,26 +1903,24 @@ For example, given the following model, .. code-tab:: smithy resource Forecast { - identifiers: { - forecastId: ForecastId, - }, - read: GetForecast, + identifiers: { forecastId: ForecastId } + read: GetForecast } @readonly operation GetForecast { - input: GetForecastInput, + input: GetForecastInput output: GetForecastOutput } structure GetForecastInput { @required - forecastId: ForecastId, + forecastId: ForecastId } structure GetForecastOutput { @required - weather: WeatherData, + weather: WeatherData } .. code-tab:: json @@ -1996,20 +1992,18 @@ Given the following model, .. code-tab:: smithy resource Forecast { - identifiers: { - forecastId: ForecastId, - }, - collectionOperations: [BatchPutForecasts], + identifiers: { forecastId: ForecastId } + collectionOperations: [BatchPutForecasts] } operation BatchPutForecasts { - input: BatchPutForecastsInput, + input: BatchPutForecastsInput output: BatchPutForecastsOutput } structure BatchPutForecastsInput { @required - forecasts: BatchPutForecastList, + forecasts: BatchPutForecastList } .. code-tab:: json @@ -2073,28 +2067,28 @@ For example, given the following, resource Forecast { // continued from above - resources: [HistoricalForecast], + resources: [HistoricalForecast] } resource HistoricalForecast { identifiers: { - forecastId: ForecastId, - historicalId: HistoricalForecastId, - }, - read: GetHistoricalForecast, - list: ListHistoricalForecasts, + forecastId: ForecastId + historicalId: HistoricalForecastId + } + read: GetHistoricalForecast + list: ListHistoricalForecasts } @readonly operation GetHistoricalForecast { - input: GetHistoricalForecastInput, + input: GetHistoricalForecastInput output: GetHistoricalForecastOutput } structure GetHistoricalForecastInput { @required @resourceIdentifier("forecastId") - customForecastIdName: ForecastId, + customForecastIdName: ForecastId @required @resourceIdentifier("historicalId") @@ -2127,15 +2121,13 @@ The following example defines a resource with each lifecycle method: namespace smithy.example resource Forecast { - identifiers: { - forecastId: ForecastId, - }, - put: PutForecast, - create: CreateForecast, - read: GetForecast, - update: UpdateForecast, - delete: DeleteForecast, - list: ListForecasts, + identifiers: { forecastId: ForecastId } + put: PutForecast + create: CreateForecast + read: GetForecast + update: UpdateForecast + delete: DeleteForecast + list: ListForecasts } @@ -2157,14 +2149,14 @@ The following example defines the ``PutForecast`` operation. @idempotent operation PutForecast { - input: PutForecastInput, + input: PutForecastInput output: PutForecastOutput } structure PutForecastInput { // The client provides the resource identifier. @required - forecastId: ForecastId, + forecastId: ForecastId chanceOfRain: Float } @@ -2199,19 +2191,19 @@ The following example defines the ``CreateForecast`` operation. .. code-block:: smithy operation CreateForecast { - input: CreateForecastInput, + input: CreateForecastInput output: CreateForecastOutput } operation CreateForecast { - input: CreateForecastInput, + input: CreateForecastInput output: CreateForecastOutput } structure CreateForecastInput { // No identifier is provided by the client, so the service is // responsible for providing the identifier of the resource. - chanceOfRain: Float, + chanceOfRain: Float } @@ -2232,14 +2224,14 @@ For example: @readonly operation GetForecast { - input: GetForecastInput, - output: GetForecastOutput, + input: GetForecastInput + output: GetForecastOutput errors: [ResourceNotFound] } structure GetForecastInput { @required - forecastId: ForecastId, + forecastId: ForecastId } @@ -2259,16 +2251,16 @@ For example: .. code-block:: smithy operation UpdateForecast { - input: UpdateForecastInput, - output: UpdateForecastOutput, + input: UpdateForecastInput + output: UpdateForecastOutput errors: [ResourceNotFound] } structure UpdateForecastInput { @required - forecastId: ForecastId, + forecastId: ForecastId - chanceOfRain: Float, + chanceOfRain: Float } @@ -2289,14 +2281,14 @@ For example: @idempotent operation DeleteForecast { - input: DeleteForecastInput, - output: DeleteForecastOutput, + input: DeleteForecastInput + output: DeleteForecastOutput errors: [ResourceNotFound] } structure DeleteForecastInput { @required - forecastId: ForecastId, + forecastId: ForecastId } @@ -2320,17 +2312,17 @@ For example: @readonly @paginated operation ListForecasts { - input: ListForecastsInput, + input: ListForecastsInput output: ListForecastsOutput } structure ListForecastsInput { - maxResults: Integer, + maxResults: Integer nextToken: String } structure ListForecastsOutput { - nextToken: String, + nextToken: String @required forecasts: ForecastList } @@ -2690,24 +2682,24 @@ The following example defines two custom traits: ``beta`` and @trait(selector: "string", conflicts: [beta]) structure structuredTrait { @required - lorem: StringShape, + lorem: StringShape @required - ipsum: StringShape, + ipsum: StringShape - dolor: StringShape, + dolor: StringShape } // Apply the "beta" trait to the "foo" member. structure MyShape { @required @beta - foo: StringShape, + foo: StringShape } // Apply the structuredTrait to the string. @structuredTrait( - lorem: "This is a custom trait!", + lorem: "This is a custom trait!" ipsum: "lorem and ipsum are both required values.") string StringShape @@ -2840,7 +2832,7 @@ after adding a member to the ``foo`` trait: @trait structure foo { - baz: String, + baz: String } @foo(baz: "bar") diff --git a/docs/source/1.0/spec/core/protocol-traits.rst b/docs/source/1.0/spec/core/protocol-traits.rst index c5069a9ae20..a851048d688 100644 --- a/docs/source/1.0/spec/core/protocol-traits.rst +++ b/docs/source/1.0/spec/core/protocol-traits.rst @@ -76,7 +76,7 @@ The following example defines a service that supports both the hypothetical @jsonExample @xmlExample service WeatherService { - version: "2017-02-11", + version: "2017-02-11" } .. code-tab:: json @@ -129,7 +129,7 @@ support configuration settings. @configurableExample(version: "1.0") service WeatherService { - version: "2017-02-11", + version: "2017-02-11" } @@ -157,9 +157,9 @@ Given the following structure definition, structure MyStructure { @jsonName("Foo") - foo: String, + foo: String - bar: String, + bar: String } .. code-tab:: json diff --git a/docs/source/1.0/spec/core/resource-traits.rst b/docs/source/1.0/spec/core/resource-traits.rst index eb63f5119b1..25160d0ada9 100644 --- a/docs/source/1.0/spec/core/resource-traits.rst +++ b/docs/source/1.0/spec/core/resource-traits.rst @@ -157,14 +157,14 @@ The following example creates a reference to a ``HistoricalForecast`` resource resource HistoricalForecast { identifiers: { - forecastId: ForecastId, - historicalId: HistoricalForecastId, + forecastId: ForecastId + historicalId: HistoricalForecastId } } @references([{resource: HistoricalForecast}]) structure HistoricalReference { - forecastId: ForecastId, + forecastId: ForecastId historicalId: HistoricalForecastId } @@ -184,16 +184,16 @@ defined if needed. For example: @references([ { - resource: HistoricalForecast, + resource: HistoricalForecast ids: { - forecastId: "customForecastId", + forecastId: "customForecastId" historicalId: "customHistoricalId" } } ]) structure AnotherHistoricalReference { - customForecastId: String, - customHistoricalId: String, + customForecastId: String + customHistoricalId: String } .. rubric:: Additional examples @@ -205,31 +205,31 @@ The following example defines several references: .. code-tab:: smithy @references([ - {resource: Forecast}, - {resource: ShapeName}, - {resource: Meteorologist}, + {resource: Forecast} + {resource: ShapeName} + {resource: Meteorologist} { - resource: com.foo.baz#Object, - service: com.foo.baz#Service, - ids: {bucket: "bucketName", object: "objectKey"}, + resource: com.foo.baz#Object + service: com.foo.baz#Service + ids: {bucket: "bucketName", object: "objectKey"} ]) structure ForecastInformation { - someId: SomeShapeIdentifier, + someId: SomeShapeIdentifier @required - forecastId: ForecastId, + forecastId: ForecastId @required - meteorologistId: MeteorologistId, + meteorologistId: MeteorologistId @required - otherData: SomeOtherShape, + otherData: SomeOtherShape @required - bucketName: BucketName, + bucketName: BucketName @required - objectKey: ObjectKey, + objectKey: ObjectKey } .. rubric:: References on string shapes @@ -242,7 +242,7 @@ property in the reference. resource SimpleResource { identifiers: { - foo: String, + foo: String } } @@ -292,28 +292,28 @@ match for the name of the resource identifier. resource File { identifiers: { - directory: "String", - fileName: "String", - }, - read: GetFile, + directory: "String" + fileName: "String" + } + read: GetFile } @readonly operation GetFile { - input: GetFileInput, - output: GetFileOutput, + input: GetFileInput + output: GetFileOutput errors: [NoSuchResource] } structure GetFileInput { @required - directory: String, + directory: String // resourceIdentifier is used because the input member name // does not match the resource identifier name @resourceIdentifier("fileName") @required - name: String, + name: String } diff --git a/docs/source/1.0/spec/core/selectors.rst b/docs/source/1.0/spec/core/selectors.rst index 307d54f6e1f..a0ff1fbabd6 100644 --- a/docs/source/1.0/spec/core/selectors.rst +++ b/docs/source/1.0/spec/core/selectors.rst @@ -719,17 +719,17 @@ in the closure of a service. @trait(selector: "service") list allowedTags { - member: String, + member: String } @allowedTags(["internal", "external"]) service MyService { - version: "2020-04-28", + version: "2020-04-28" operations: [OperationA, OperationB, OperationC, OperationD] } operation OperationA { - input: OperationAInput, + input: OperationAInput } @tags(["internal"]) @@ -742,20 +742,20 @@ in the closure of a service. operation OperationD {} structure OperationAInput { - badValue: BadEnum, - goodValue: GoodEnum, + badValue: BadEnum + goodValue: GoodEnum } @enum([ - {value: "a", tags: ["internal"]}, - {value: "b", tags: ["invalid"]}, + {value: "a", tags: ["internal"]} + {value: "b", tags: ["invalid"]} ]) string BadEnum @enum([ - {value: "a"}, - {value: "b", tags: ["internal", "external"]}, - {value: "c", tags: ["internal"]}, + {value: "a"} + {value: "b", tags: ["internal", "external"]} + {value: "c", tags: ["internal"]} ]) string GoodEnum @@ -1421,9 +1421,9 @@ matches the disqualifier selector. @aws.api#dataPlane service Example { - version: "2020-09-08", - resources: [Foo], - operations: [OperationA], + version: "2020-09-08" + resources: [Foo] + operations: [OperationA] } operation OperationA {} @@ -1514,7 +1514,7 @@ operation: @httpBasicAuth @httpBearerAuth service MyService { - version: "2020-04-21", + version: "2020-04-21" operations: [HasDigestAuth, HasBasicAuth, NoAuth] } diff --git a/docs/source/1.0/spec/core/stream-traits.rst b/docs/source/1.0/spec/core/stream-traits.rst index 9bfc88a7d1b..8100a8cf925 100644 --- a/docs/source/1.0/spec/core/stream-traits.rst +++ b/docs/source/1.0/spec/core/stream-traits.rst @@ -46,13 +46,13 @@ Validation .. code-tab:: smithy operation StreamingOperation { - output: StreamingOperationOutput, + output: StreamingOperationOutput } structure StreamingOperationOutput { @required streamId: String - output: StreamingBlob, + output: StreamingBlob } @streaming @@ -124,18 +124,18 @@ stream in its input by referencing a member that targets a union: } structure PublishMessagesInput { - room: String, - messages: PublishEvents, + room: String + messages: PublishEvents } @streaming union PublishEvents { - message: Message, - leave: LeaveEvent, + message: Message + leave: LeaveEvent } structure Message { - message: String, + message: String } structure LeaveEvent {} @@ -203,19 +203,19 @@ stream in its output: } structure SubscribeToMovementsOutput { - movements: MovementEvents, + movements: MovementEvents } @streaming union MovementEvents { - up: Movement, - down: Movement, - left: Movement, - right: Movement, + up: Movement + down: Movement + left: Movement + right: Movement } structure Movement { - velocity: Float, + velocity: Float } .. code-tab:: json @@ -314,19 +314,19 @@ service, followed by the events sent in the payload of the HTTP message. structure PublishMessagesInput { @httpLabel @required - room: String, + room: String @httpPayload - messages: MessageStream, + messages: MessageStream } @streaming union MessageStream { - message: Message, + message: Message } structure Message { - message: String, + message: String } .. code-tab:: json @@ -414,7 +414,7 @@ message. @http(method: "GET", uri: "/messages/{room}") operation SubscribeToMessages { - input: SubscribeToMessagesInput, + input: SubscribeToMessagesInput output: SubscribeToMessagesOutput } @@ -426,10 +426,10 @@ message. structure SubscribeToMessagesOutput { @httpHeader("X-Connection-Lifetime") - connectionLifetime: Integer, + connectionLifetime: Integer @httpPayload - messages: MessageStream, + messages: MessageStream } .. code-tab:: json @@ -519,14 +519,14 @@ on the name of an event. For example, given the following event stream: } structure SubscribeToEventsOutput { - events: Events, + events: Events } @streaming union Events { - a: Event1, - b: Event2, - c: Event3, + a: Event1 + b: Event2 + c: Event3 } structure Event1 {} @@ -564,13 +564,13 @@ headers and the "c" member as the payload. structure ExampleEvent { @eventHeader - a: String, + a: String @eventHeader - b: String, + b: String @eventPayload - c: Blob, + c: Blob } .. code-tab:: json @@ -613,9 +613,9 @@ based protocol, the event payload is serialized as a JSON object: .. code-tab:: smithy structure ExampleEvent { - a: String, - b: String, - c: Blob, + a: String + b: String + c: Blob } .. code-tab:: json @@ -677,10 +677,10 @@ The following example defines multiple event headers: structure ExampleEvent { @eventHeader - a: String, + a: String @eventHeader - b: String, + b: String } .. code-tab:: json @@ -747,10 +747,10 @@ of an event: structure ExampleEvent { @eventPayload - a: String, + a: String @eventHeader - b: String, + b: String } .. code-tab:: json @@ -785,8 +785,8 @@ The following structure is **invalid** because the "a" member is bound to the structure ExampleEvent { @eventPayload - a: String, + a: String - b: String, + b: String // ^ Error: not bound to an eventHeader. } diff --git a/docs/source/1.0/spec/core/type-refinement-traits.rst b/docs/source/1.0/spec/core/type-refinement-traits.rst index 11b82476393..12cdbf0db2b 100644 --- a/docs/source/1.0/spec/core/type-refinement-traits.rst +++ b/docs/source/1.0/spec/core/type-refinement-traits.rst @@ -132,7 +132,7 @@ in Java). @httpError(429) structure ThrottlingError { @required - message: String, + message: String } @@ -188,7 +188,7 @@ The following example defines a :ref:`map ` shape that MAY contain @sparse map SparseMap { - key: String, + key: String value: String } diff --git a/docs/source/1.0/spec/core/xml-traits.rst b/docs/source/1.0/spec/core/xml-traits.rst index ca742620d2a..88cf865f78f 100644 --- a/docs/source/1.0/spec/core/xml-traits.rst +++ b/docs/source/1.0/spec/core/xml-traits.rst @@ -41,7 +41,7 @@ For example, given the following: .. code-block:: smithy structure MyStructure { - foo: String, + foo: String } The XML serialization is: @@ -80,12 +80,12 @@ members that target it. Given the following: @xmlName("AStruct") structure A { - b: B, + b: B } @xmlName("BStruct") structure B { - hello: String, + hello: String } .. code-tab:: json @@ -146,7 +146,7 @@ The following table defines how simple types are serialized in XML documents. .. code-block:: smithy structure Struct { - binary: Blob, + binary: Blob } given a value of ``value`` for ``binary``: @@ -187,7 +187,7 @@ The following table defines how simple types are serialized in XML documents. .. code-block:: smithy structure Struct { - date: Timestamp, + date: Timestamp } given a value of ``1578255206`` for ``date``: @@ -227,7 +227,7 @@ following: } list MyList { - member: String, + member: String } The XML serialization of ``Foo`` is: @@ -255,7 +255,7 @@ change the nested element name. For example, given the following: list MyList { @xmlName("Item") - member: String, + member: String } .. code-tab:: json @@ -308,7 +308,7 @@ example, given the following: structure Foo { @xmlFlattened - flat: MyList, + flat: MyList } The XML serialization of ``Foo`` is: @@ -329,7 +329,7 @@ the name of the repeated XML element. For example, given the following: union Choice { @xmlFlattened @xmlName("Hi") - flat: MySet, + flat: MySet } set MySet { @@ -354,7 +354,7 @@ following: union Choice { @xmlFlattened - flat: MySet, + flat: MySet } set MySet { @@ -396,8 +396,8 @@ serialized in a nested element named ``entry`` that contains a nested } map MyMap { - key: String, - value: String, + key: String + value: String } The XML serialization of ``Foo`` is: @@ -428,10 +428,10 @@ to change the nested element names. For example, given the following: map MyMap { @xmlName("Name") - key: String, + key: String @xmlName("Setting") - value: String, + value: String } The XML serialization of ``Foo`` is: @@ -468,8 +468,8 @@ into a containing structure/union. For example, given the following: } map MyMap { - key: String, - value: String, + key: String + value: String } .. code-tab:: json @@ -527,11 +527,11 @@ the name of the repeated XML element. For example, given the following: union Choice { @xmlFlattened @xmlName("Hi") - flat: MyMap, + flat: MyMap } map MyMap { - key: String, + key: String value: String } @@ -563,15 +563,15 @@ the following: union Choice { @xmlFlattened @xmlName("Hi") - flat: MyMap, + flat: MyMap } map MyMap { @xmlName("Name") - key: String, + key: String @xmlName("Setting") - value: String, + value: String } The XML serialization of ``Choice`` is: @@ -623,9 +623,9 @@ member name. For example, given the following: structure MyStructure { @xmlAttribute - foo: String, + foo: String - bar: String, + bar: String } .. code-tab:: json @@ -723,13 +723,13 @@ Given the following: structure Foo { @xmlFlattened - flat: MyList, + flat: MyList - nested: MyList, + nested: MyList } list MyList { - member: String, + member: String } .. code-tab:: json @@ -783,9 +783,9 @@ Maps can be flattened into structures too. Given the following: structure Foo { @xmlFlattened - flat: MyMap, + flat: MyMap - notFlat: MyMap, + notFlat: MyMap } map MyMap { @@ -879,9 +879,9 @@ elements using the same name as the structure member name. Given the following: structure MyStructure { @xmlName("Foo") - foo: String, + foo: String - bar: String, + bar: String } .. code-tab:: json @@ -922,7 +922,7 @@ following structure AnotherStructure { @xmlName("hello:foo") - foo: String, + foo: String } The XML serialization is: @@ -977,8 +977,8 @@ Given the following: @xmlNamespace(uri: "http://foo.com") structure MyStructure { - foo: String, - bar: String, + foo: String + bar: String } .. code-tab:: json @@ -1020,10 +1020,10 @@ Given the following: @xmlNamespace(uri: "http://foo.com", prefix: "baz") structure MyStructure { - foo: String, + foo: String @xmlName("baz:bar") - bar: String, + bar: String } The XML serialization is: diff --git a/docs/source/1.0/spec/http-protocol-compliance-tests.rst b/docs/source/1.0/spec/http-protocol-compliance-tests.rst index 014f336d38b..0527c843072 100644 --- a/docs/source/1.0/spec/http-protocol-compliance-tests.rst +++ b/docs/source/1.0/spec/http-protocol-compliance-tests.rst @@ -256,22 +256,22 @@ that uses :ref:`HTTP binding traits `. @http(method: "POST", uri: "/") @httpRequestTests([ { - id: "say_hello", - protocol: exampleProtocol, + id: "say_hello" + protocol: exampleProtocol params: { - "greeting": "Hi", - "name": "Teddy", + "greeting": "Hi" + "name": "Teddy" "query": "Hello there" - }, - method: "POST", - uri: "/", + } + method: "POST" + uri: "/" queryParams: [ "Hi=Hello%20there" - ], + ] headers: { - "X-Greeting": "Hi", - }, - body: "{\"name\": \"Teddy\"}", + "X-Greeting": "Hi" + } + body: "{\"name\": \"Teddy\"}" bodyMediaType: "application/json" } ]) @@ -281,10 +281,10 @@ that uses :ref:`HTTP binding traits `. structure SayHelloInput { @httpHeader("X-Greeting") - greeting: String, + greeting: String @httpQuery("Hi") - query: String, + query: String name: String } @@ -488,12 +488,12 @@ that uses :ref:`HTTP binding traits `. @http(method: "POST", uri: "/") @httpResponseTests([ { - id: "say_goodbye", - protocol: exampleProtocol, - params: {farewell: "Bye"}, - code: 200, + id: "say_goodbye" + protocol: exampleProtocol + params: {farewell: "Bye"} + code: 200 headers: { - "X-Farewell": "Bye", + "X-Farewell": "Bye" "Content-Length": "0" } } @@ -504,7 +504,7 @@ that uses :ref:`HTTP binding traits `. structure SayGoodbyeOutput { @httpHeader("X-Farewell") - farewell: String, + farewell: String } .. code-tab:: json @@ -577,20 +577,20 @@ that uses :ref:`HTTP binding traits `. @httpError(400) @httpResponseTests([ { - id: "invalid_greeting", - protocol: exampleProtocol, - params: {foo: "baz", message: "Hi"}, - code: 400, - headers: {"X-Foo": "baz"}, - body: "{\"message\": \"Hi\"}", - bodyMediaType: "application/json", + id: "invalid_greeting" + protocol: exampleProtocol + params: {foo: "baz", message: "Hi"} + code: 400 + headers: {"X-Foo": "baz"} + body: "{\"message\": \"Hi\"}" + bodyMediaType: "application/json" } ]) structure InvalidGreeting { @httpHeader("X-Foo") - foo: String, + foo: String - message: String, + message: String } .. code-tab:: json diff --git a/docs/source/1.0/spec/mqtt.rst b/docs/source/1.0/spec/mqtt.rst index ac2cf10a945..63a4f710114 100644 --- a/docs/source/1.0/spec/mqtt.rst +++ b/docs/source/1.0/spec/mqtt.rst @@ -102,13 +102,13 @@ and ``{second}``, in the MQTT topic template: structure ExampleOperationInput { @required @topicLabel - first: String, + first: String @required @topicLabel - second: String, + second: String - message: String, + message: String } .. code-tab:: json @@ -216,10 +216,10 @@ The following example defines an operation that publishes messages to the structure PostFooInput { @required @topicLabel - bar: String, + bar: String someValue: String, - anotherValue: Boolean, + anotherValue: Boolean } .. code-tab:: json @@ -326,27 +326,27 @@ topic using an :ref:`event stream `: @subscribe("events/{id}") operation SubscribeForEvents { - input: SubscribeForEventsInput, + input: SubscribeForEventsInput output: SubscribeForEventsOutput } structure SubscribeForEventsInput { @required @topicLabel - id: String, + id: String } structure SubscribeForEventsOutput { - events: EventStream, + events: EventStream } @streaming union EventStream { - message: Event, + message: Event } structure Event { - message: String, + message: String } .. code-tab:: json @@ -531,15 +531,19 @@ MQTT protocol bindings. @protocolDefinition structure mqttJson {} - @trait(selector: "operation:not(-[output]->)", - conflicts: ["smithy.mqtt#subscribe"]) + @trait( + selector: "operation:not(-[output]->)" + conflicts: ["smithy.mqtt#subscribe"] + ) @tags(["diff.error.const"]) // Matches one or more characters that are not "#" or "+". @pattern("^[^#+]+$") string publish - @trait(selector: "operation:test(-[output]-> structure > member > union[trait|streaming])", - conflicts: ["smithy.mqtt#publish"]) + @trait( + selector: "operation:test(-[output]-> structure > member > union[trait|streaming])" + conflicts: [publish] + ) @tags(["diff.error.const"]) // Matches one or more characters that are not "#" or "+". @pattern("^[^#+]+$") diff --git a/docs/source/1.0/spec/waiters.rst b/docs/source/1.0/spec/waiters.rst index 7fa42a01c16..84e3dc6eefc 100644 --- a/docs/source/1.0/spec/waiters.rst +++ b/docs/source/1.0/spec/waiters.rst @@ -54,16 +54,16 @@ exists: @waitable( BucketExists: { - documentation: "Wait until a bucket exists", + documentation: "Wait until a bucket exists" acceptors: [ { - state: "success", + state: "success" matcher: { success: true } - }, + } { - state: "retry", + state: "retry" matcher: { errorType: "NotFound" } @@ -72,8 +72,8 @@ exists: } ) operation HeadBucket { - input: HeadBucketInput, - output: HeadBucketOutput, + input: HeadBucketInput + output: HeadBucketOutput errors: [NotFound] } @@ -602,26 +602,26 @@ triggered if the ``status`` property equals ``failed``. @waitable( ThingExists: { - description: "Waits until a thing has been created", + description: "Waits until a thing has been created" acceptors: [ // Fail-fast if the thing transitions to a "failed" state. { - state: "failure", + state: "failure" matcher: { output: { - path: "status", - comparator: "stringEquals", + path: "status" + comparator: "stringEquals" expected: "failed" } } - }, + } // Succeed when the thing enters into a "success" state. { - state: "success", + state: "success" matcher: { output: { - path: "status", - comparator: "stringEquals", + path: "status" + comparator: "stringEquals" expected: "success" } } @@ -630,13 +630,13 @@ triggered if the ``status`` property equals ``failed``. } ) operation GetThing { - input: GetThingInput, - output: GetThingOutput, + input: GetThingInput + output: GetThingOutput } structure GetThingInput { @required - name: String, + name: String } structure GetThingOutput { @@ -658,8 +658,8 @@ provided groups on input matches the number of provided groups on output: acceptors: [ { inputOutput: { - path: "length(input.groups) == length(output.groups)", - expected: "true", + path: "length(input.groups) == length(output.groups)" + expected: "true" comparator: "booleanEquals" } } @@ -667,8 +667,8 @@ provided groups on input matches the number of provided groups on output: } ) operation ListGroups { - input: ListGroupsInput, - output: ListGroupsOutput, + input: ListGroupsInput + output: ListGroupsOutput } @@ -745,11 +745,11 @@ is unnecessary: { acceptors: [ { - state: "failure", + state: "failure" matcher: { errorType: "ValidationError" } - }, + } // other acceptors... ] } @@ -764,11 +764,11 @@ specific errors. For example, the following matcher is unnecessary: { acceptors: [ { - state: "retry", + state: "retry" matcher: { success: true } - }, + } // other acceptors... ] } @@ -824,24 +824,24 @@ the ``StartResource`` API operation. @waitable( ResourceRunning: { - description: "Waits for the resource to be running", + description: "Waits for the resource to be running" acceptors: [ { - state: "failure", + state: "failure" matcher: { output: { - path: "State", - expected: "Stopped", + path: "State" + expected: "Stopped" comparator: "stringEquals" } } }, { - state: "success", + state: "success" matcher: { output: { - path: "State", - expected: "Running", + path: "State" + expected: "Running" comparator: "stringEquals" } } @@ -851,8 +851,8 @@ the ``StartResource`` API operation. } ) operation GetResource { - input: GetResourceInput, - output: GetResourceOutput, + input: GetResourceInput + output: GetResourceOutput } diff --git a/docs/source/quickstart.rst b/docs/source/quickstart.rst index d2e93d0e4be..cb9f396cc17 100644 --- a/docs/source/quickstart.rst +++ b/docs/source/quickstart.rst @@ -105,29 +105,15 @@ weather service. ``Weather`` is a :ref:`service` shape that is defined inside of a :ref:`namespace `. -.. tabs:: - - .. code-tab:: smithy +.. code-block:: smithy - namespace example.weather + namespace example.weather - /// Provides weather forecasts. - /// Triple slash comments attach documentation to shapes. - service Weather { - version: "2006-03-01" - } - - .. code-tab:: json - - { - "smithy": "1.0", - "shapes": { - "example.weather#Weather": { - "type": "service", - "version": "2006-03-01" - } - } - } + /// Provides weather forecasts. + /// Triple slash comments attach documentation to shapes. + service Weather { + version: "2006-03-01" + } .. admonition:: What's that syntax? :class: note @@ -150,64 +136,25 @@ Defining resources A resource is contained within a service or another resource. Resources have identifiers, operations, and any number of child resources. -.. tabs:: - - .. code-tab:: smithy - - namespace example.weather - - /// Provides weather forecasts. - service Weather { - version: "2006-03-01", - resources: [City] - } +.. code-block:: smithy - resource City { - identifiers: { cityId: CityId }, - read: GetCity, - list: ListCities, - } + namespace example.weather - // "pattern" is a trait. - @pattern("^[A-Za-z0-9 ]+$") - string CityId + /// Provides weather forecasts. + service Weather { + version: "2006-03-01" + resources: [City] + } - .. code-tab:: json + resource City { + identifiers: { cityId: CityId } + read: GetCity + list: ListCities + } - { - "smithy": "1.0", - "shapes": { - "example.weather#Weather": { - "type": "service", - "version": "2006-03-01", - "resources": [ - { - "target": "example.weather#City" - } - ] - }, - "example.weather#City": { - "type": "resource", - "identifiers": { - "cityId": { - "target": "example.weather#CityId" - } - }, - "read": { - "target": "example.weather#GetCity" - }, - "list": { - "target": "example.weather#ListCities" - } - }, - "example.weather#CityId": { - "type": "string", - "traits": { - "smithy.api#pattern": "^[A-Za-z0-9 ]+$" - } - } - } - } + // "pattern" is a trait. + @pattern("^[A-Za-z0-9 ]+$") + string CityId Because the ``Weather`` service contains many cities, the ``City`` resource defines an :ref:`identifier `. *Identifiers* are used @@ -222,59 +169,19 @@ identity of the resource. Each ``City`` has a single ``Forecast``. This can be defined by adding the ``Forecast`` to the ``resources`` property of the ``City``. -.. tabs:: - - .. code-tab:: smithy - - resource City { - identifiers: { cityId: CityId }, - read: GetCity, - list: ListCities, - resources: [Forecast], - } - - resource Forecast { - identifiers: { cityId: CityId }, - read: GetForecast, - } +.. code-block:: smithy - .. code-tab:: json + resource City { + identifiers: { cityId: CityId } + read: GetCity + list: ListCities + resources: [Forecast] + } - { - "smithy": "1.0", - "shapes": { - "example.weather#City": { - "type": "resource", - "identifiers": { - "cityId": { - "target": "example.weather#CityId" - } - }, - "read": { - "target": "example.weather#GetCity" - }, - "list": { - "target": "example.weather#ListCities" - }, - "resources": [ - { - "target": "example.weather#Forecast" - } - ] - }, - "example.weather#Forecast": { - "type": "resource", - "identifiers": { - "cityId": { - "target": "example.weather#CityId" - } - }, - "read": { - "target": "example.weather#GetForecast" - } - } - } - } + resource Forecast { + identifiers: { cityId: CityId } + read: GetForecast + } Child resources must define the exact same identifiers property of their parent, but they are allowed to add any number of additional identifiers if @@ -303,192 +210,68 @@ lifecycle operations helps automated tooling reason about your API. Let's define the operation used to "read" a ``City``. -.. tabs:: - - .. code-tab:: smithy - - @readonly - operation GetCity { - input: GetCityInput, - output: GetCityOutput, - errors: [NoSuchResource] - } +.. code-block:: smithy - structure GetCityInput { - // "cityId" provides the identifier for the resource and - // has to be marked as required. - @required - cityId: CityId - } - - structure GetCityOutput { - // "required" is used on output to indicate if the service - // will always provide a value for the member. - @required - name: String, + @readonly + operation GetCity { + input: GetCityInput + output: GetCityOutput + errors: [NoSuchResource] + } - @required - coordinates: CityCoordinates, - } + structure GetCityInput { + // "cityId" provides the identifier for the resource and + // has to be marked as required. + @required + cityId: CityId + } - structure CityCoordinates { - @required - latitude: Float, + structure GetCityOutput { + // "required" is used on output to indicate if the service + // will always provide a value for the member. + @required + name: String - @required - longitude: Float, - } + @required + coordinates: CityCoordinates + } - // "error" is a trait that is used to specialize - // a structure as an error. - @error("client") - structure NoSuchResource { - @required - resourceType: String - } + structure CityCoordinates { + @required + latitude: Float - .. code-tab:: json + @required + longitude: Float + } - { - "smithy": "1.0", - "shapes": { - "example.weather#GetCity": { - "type": "operation", - "input": { - "target": "example.weather#GetCityInput" - }, - "output": { - "target": "example.weather#GetCityOutput" - }, - "errors": [ - { - "target": "example.weather#NoSuchResource" - } - ] - }, - "example.weather#GetCityInput": { - "type": "structure", - "members": { - "cityId": { - "target": "example.weather#CityId", - "traits": { - "smithy.api#required": true - } - } - } - }, - "example.weather#GetCityOutput": { - "type": "structure", - "members": { - "name": { - "target": "smithy.api#String", - "traits": { - "smithy.api#required": true - } - }, - "coordinates": { - "target": "example.weather#CityCoordinates", - "traits": { - "smithy.api#required": true - } - } - } - }, - "example.weather#CityCoordinates": { - "type": "structure", - "members": { - "latitude": { - "target": "smithy.api#Float", - "traits": { - "smithy.api#required": true - } - }, - "longitude": { - "target": "smithy.api#Float", - "traits": { - "smithy.api#required": true - } - } - } - }, - "example.weather#NoSuchResource": { - "type": "structure", - "members": { - "resourceType": { - "target": "smithy.api#String", - "traits": { - "smithy.api#required": true - } - } - }, - "traits": { - "smithy.api#error": "client" - } - } - } - } + // "error" is a trait that is used to specialize + // a structure as an error. + @error("client") + structure NoSuchResource { + @required + resourceType: String + } And define the operation used to "read" a ``Forecast``. -.. tabs:: - - .. code-tab:: smithy +.. code-block:: smithy - @readonly - operation GetForecast { - input: GetForecastInput, - output: GetForecastOutput - } - - // "cityId" provides the only identifier for the resource since - // a Forecast doesn't have its own. - structure GetForecastInput { - @required - cityId: CityId, - } - - structure GetForecastOutput { - chanceOfRain: Float - } + @readonly + operation GetForecast { + input: GetForecastInput + output: GetForecastOutput + } - .. code-tab:: json + // "cityId" provides the only identifier for the resource since + // a Forecast doesn't have its own. + structure GetForecastInput { + @required + cityId: CityId + } - { - "smithy": "1.0", - "shapes": { - "example.weather#GetForecast": { - "type": "operation", - "input": { - "target": "example.weather#GetForecastInput" - }, - "output": { - "target": "example.weather#GetForecastOutput" - }, - "traits": { - "smithy.api#readonly": true - } - }, - "example.weather#GetForecastInput": { - "type": "structure", - "members": { - "cityId": { - "target": "example.weather#CityId", - "traits": { - "smithy.api#required": true - } - } - } - }, - "example.weather#GetForecastOutput": { - "type": "structure", - "members": { - "chanceOfRain": { - "target": "smithy.api#Float" - } - } - } - } - } + structure GetForecastOutput { + chanceOfRain: Float + } .. admonition:: Review :class: tip @@ -510,141 +293,55 @@ is a :ref:`collection operation `, and as such, MUST NOT bind the identifier of a ``City`` to its input structure; we are listing cities, so there's no way we could provide a ``City`` identifier. -.. tabs:: - - .. code-tab:: smithy - - /// Provides weather forecasts. - @paginated(inputToken: "nextToken", outputToken: "nextToken", - pageSize: "pageSize") - service Weather { - version: "2006-03-01", - resources: [City] - } - - // The paginated trait indicates that the operation may - // return truncated results. Applying this trait to the service - // sets default pagination configuration settings on each operation. - @paginated(items: "items") - @readonly - operation ListCities { - input: ListCitiesInput, - output: ListCitiesOutput - } - - structure ListCitiesInput { - nextToken: String, - pageSize: Integer - } +.. code-block:: smithy + + /// Provides weather forecasts. + @paginated( + inputToken: "nextToken" + outputToken: "nextToken" + pageSize: "pageSize" + ) + service Weather { + version: "2006-03-01" + resources: [City] + } - structure ListCitiesOutput { - nextToken: String, + // The paginated trait indicates that the operation may + // return truncated results. Applying this trait to the service + // sets default pagination configuration settings on each operation. + @paginated(items: "items") + @readonly + operation ListCities { + input: ListCitiesInput + output: ListCitiesOutput + } - @required - items: CitySummaries, - } + structure ListCitiesInput { + nextToken: String + pageSize: Integer + } - // CitySummaries is a list of CitySummary structures. - list CitySummaries { - member: CitySummary - } + structure ListCitiesOutput { + nextToken: String - // CitySummary contains a reference to a City. - @references([{resource: City}]) - structure CitySummary { - @required - cityId: CityId, + @required + items: CitySummaries + } - @required - name: String, - } + // CitySummaries is a list of CitySummary structures. + list CitySummaries { + member: CitySummary + } - .. code-tab:: json + // CitySummary contains a reference to a City. + @references([{resource: City}]) + structure CitySummary { + @required + cityId: CityId - { - "smithy": "1.0", - "shapes": { - "example.weather#Weather": { - "type": "service", - "version": "2006-03-01", - "resources": [ - { - "target": "example.weather#City" - } - ], - "traits": { - "smithy.api#paginated": { - "inputToken": "nextToken", - "outputToken": "nextToken", - "pageSize": "pageSize" - } - } - }, - "example.weather#ListCities": { - "type": "operation", - "input": { - "target": "example.weather#ListCitiesInput" - }, - "output": { - "target": "example.weather#ListCitiesOutput" - }, - "traits": { - "smithy.api#readonly": true, - "smithy.api#paginated": { - "items": "items" - } - } - }, - "example.weather#ListCitiesInput": { - "type": "structure", - "members": { - "nextToken": { - "target": "smithy.api#String" - }, - "pageSize": { - "target": "smithy.api#Integer" - } - } - }, - "example.weather#ListCitiesOutput": { - "type": "structure", - "members": { - "nextToken": { - "target": "smithy.api#String" - }, - "items": { - "target": "example.weather#CitySummaries", - "traits": { - "smithy.api#required": true - } - } - } - }, - "example.weather#CitySummaries": { - "type": "list", - "member": { - "target": "example.weather#CitySummary" - } - }, - "example.weather#CitySummary": { - "type": "structure", - "members": { - "cityId": { - "target": "example.weather#CityId", - "traits": { - "smithy.api#required": true - } - }, - "name": { - "target": "smithy.api#String", - "traits": { - "smithy.api#required": true - } - } - } - } - } - } + @required + name: String + } The ``ListCities`` operation is :ref:`paginated `, meaning the results of invoking the operation can be truncated, requiring subsequent @@ -677,71 +374,27 @@ service shape with no special lifecycle designation using the ``operations`` property. The following operation gets the current time from the ``Weather`` service. +.. code-block:: smithy -.. tabs:: - - .. code-tab:: smithy - - /// Provides weather forecasts. - @paginated(inputToken: "nextToken", outputToken: "nextToken", - pageSize: "pageSize") - service Weather { - version: "2006-03-01", - resources: [City], - operations: [GetCurrentTime] - } - - @readonly - operation GetCurrentTime { - output: GetCurrentTimeOutput - } + /// Provides weather forecasts. + @paginated(inputToken: "nextToken", outputToken: "nextToken", + pageSize: "pageSize") + service Weather { + version: "2006-03-01" + resources: [City] + operations: [GetCurrentTime] + } - structure GetCurrentTimeOutput { - @required - time: Timestamp - } + @readonly + operation GetCurrentTime { + output: GetCurrentTimeOutput + } - .. code-tab:: json + structure GetCurrentTimeOutput { + @required + time: Timestamp + } - { - "smithy": "1.0", - "shapes": { - "example.weather#Weather": { - "type": "service", - "version": "2006-03-01", - "resources": [ - { - "target": "example.weather#City" - } - ], - "operations": [ - { - "target": "example.weather#GetCurrentTime" - } - ] - }, - "example.weather#GetCurrentTime": { - "type": "operation", - "output": { - "target": "example.weather#GetCurrentTimeOutput" - }, - "traits": { - "smithy.api#readonly": true - } - }, - "example.weather#GetCurrentTimeOutput": { - "type": "structure", - "members": { - "time": { - "target": "smithy.api#Timestamp", - "traits": { - "smithy.api#required": true - } - } - } - } - } - } Building the Model ================== @@ -859,24 +512,27 @@ Finally, the complete ``weather.smithy`` model should look like: namespace example.weather /// Provides weather forecasts. - @paginated(inputToken: "nextToken", outputToken: "nextToken", - pageSize: "pageSize") + @paginated( + inputToken: "nextToken" + outputToken: "nextToken" + pageSize: "pageSize" + ) service Weather { - version: "2006-03-01", - resources: [City], + version: "2006-03-01" + resources: [City] operations: [GetCurrentTime] } resource City { - identifiers: { cityId: CityId }, - read: GetCity, - list: ListCities, - resources: [Forecast], + identifiers: { cityId: CityId } + read: GetCity + list: ListCities + resources: [Forecast] } resource Forecast { - identifiers: { cityId: CityId }, - read: GetForecast, + identifiers: { cityId: CityId } + read: GetForecast } // "pattern" is a trait. @@ -885,8 +541,8 @@ Finally, the complete ``weather.smithy`` model should look like: @readonly operation GetCity { - input: GetCityInput, - output: GetCityOutput, + input: GetCityInput + output: GetCityOutput errors: [NoSuchResource] } @@ -901,19 +557,19 @@ Finally, the complete ``weather.smithy`` model should look like: // "required" is used on output to indicate if the service // will always provide a value for the member. @required - name: String, + name: String @required - coordinates: CityCoordinates, + coordinates: CityCoordinates } // This structure is nested within GetCityOutput. structure CityCoordinates { @required - latitude: Float, + latitude: Float @required - longitude: Float, + longitude: Float } // "error" is a trait that is used to specialize @@ -929,20 +585,20 @@ Finally, the complete ``weather.smithy`` model should look like: @readonly @paginated(items: "items") operation ListCities { - input: ListCitiesInput, + input: ListCitiesInput output: ListCitiesOutput } structure ListCitiesInput { - nextToken: String, + nextToken: String pageSize: Integer } structure ListCitiesOutput { - nextToken: String, + nextToken: String @required - items: CitySummaries, + items: CitySummaries } // CitySummaries is a list of CitySummary structures. @@ -954,10 +610,10 @@ Finally, the complete ``weather.smithy`` model should look like: @references([{resource: City}]) structure CitySummary { @required - cityId: CityId, + cityId: CityId @required - name: String, + name: String } @readonly @@ -972,7 +628,7 @@ Finally, the complete ``weather.smithy`` model should look like: @readonly operation GetForecast { - input: GetForecastInput, + input: GetForecastInput output: GetForecastOutput } @@ -980,7 +636,7 @@ Finally, the complete ``weather.smithy`` model should look like: // a Forecast doesn't have its own. structure GetForecastInput { @required - cityId: CityId, + cityId: CityId } structure GetForecastOutput { @@ -1006,6 +662,7 @@ Finally, the complete ``weather.smithy`` model should look like: } ], "traits": { + "smithy.api#documentation": "Provides weather forecasts.", "smithy.api#paginated": { "inputToken": "nextToken", "outputToken": "nextToken", @@ -1038,13 +695,13 @@ Finally, the complete ``weather.smithy`` model should look like: "latitude": { "target": "smithy.api#Float", "traits": { - "smithy.api#required": true + "smithy.api#required": {} } }, "longitude": { "target": "smithy.api#Float", "traits": { - "smithy.api#required": true + "smithy.api#required": {} } } } @@ -1067,20 +724,20 @@ Finally, the complete ``weather.smithy`` model should look like: "cityId": { "target": "example.weather#CityId", "traits": { - "smithy.api#required": true + "smithy.api#required": {} } }, "name": { "target": "smithy.api#String", "traits": { - "smithy.api#required": true + "smithy.api#required": {} } } }, "traits": { "smithy.api#references": [ { - "resource": "City" + "resource": "example.weather#City" } ] } @@ -1110,7 +767,7 @@ Finally, the complete ``weather.smithy`` model should look like: } ], "traits": { - "smithy.api#readonly": true + "smithy.api#readonly": {} } }, "example.weather#GetCityInput": { @@ -1119,7 +776,7 @@ Finally, the complete ``weather.smithy`` model should look like: "cityId": { "target": "example.weather#CityId", "traits": { - "smithy.api#required": true + "smithy.api#required": {} } } } @@ -1127,16 +784,16 @@ Finally, the complete ``weather.smithy`` model should look like: "example.weather#GetCityOutput": { "type": "structure", "members": { - "coordinates": { - "target": "example.weather#CityCoordinates", + "name": { + "target": "smithy.api#String", "traits": { - "smithy.api#required": true + "smithy.api#required": {} } }, - "name": { - "target": "smithy.api#String", + "coordinates": { + "target": "example.weather#CityCoordinates", "traits": { - "smithy.api#required": true + "smithy.api#required": {} } } } @@ -1147,7 +804,7 @@ Finally, the complete ``weather.smithy`` model should look like: "target": "example.weather#GetCurrentTimeOutput" }, "traits": { - "smithy.api#readonly": true + "smithy.api#readonly": {} } }, "example.weather#GetCurrentTimeOutput": { @@ -1156,7 +813,7 @@ Finally, the complete ``weather.smithy`` model should look like: "time": { "target": "smithy.api#Timestamp", "traits": { - "smithy.api#required": true + "smithy.api#required": {} } } } @@ -1170,7 +827,7 @@ Finally, the complete ``weather.smithy`` model should look like: "target": "example.weather#GetForecastOutput" }, "traits": { - "smithy.api#readonly": true + "smithy.api#readonly": {} } }, "example.weather#GetForecastInput": { @@ -1179,7 +836,7 @@ Finally, the complete ``weather.smithy`` model should look like: "cityId": { "target": "example.weather#CityId", "traits": { - "smithy.api#required": true + "smithy.api#required": {} } } } @@ -1204,7 +861,7 @@ Finally, the complete ``weather.smithy`` model should look like: "smithy.api#paginated": { "items": "items" }, - "smithy.api#readonly": true + "smithy.api#readonly": {} } }, "example.weather#ListCitiesInput": { @@ -1221,14 +878,14 @@ Finally, the complete ``weather.smithy`` model should look like: "example.weather#ListCitiesOutput": { "type": "structure", "members": { + "nextToken": { + "target": "smithy.api#String" + }, "items": { "target": "example.weather#CitySummaries", "traits": { - "smithy.api#required": true + "smithy.api#required": {} } - }, - "nextToken": { - "target": "smithy.api#String" } } }, @@ -1238,7 +895,7 @@ Finally, the complete ``weather.smithy`` model should look like: "resourceType": { "target": "smithy.api#String", "traits": { - "smithy.api#required": true + "smithy.api#required": {} } } }, diff --git a/docs/themes/smithy/landing.html b/docs/themes/smithy/landing.html index aa3f15b8dc4..fc06430f9ac 100644 --- a/docs/themes/smithy/landing.html +++ b/docs/themes/smithy/landing.html @@ -17,16 +17,16 @@

Smithy

[full example]namespace example.weather
 
 service Weather {
-    version: "2006-03-01",
-    resources: [City],
+    version: "2006-03-01"
+    resources: [City]
     operations: [GetCurrentTime]
 }
 
 resource City {
-    identifiers: { cityId: CityId },
-    read: GetCity,
-    list: ListCities,
-    resources: [Forecast],
+    identifiers: { cityId: CityId }
+    read: GetCity
+    list: ListCities
+    resources: [Forecast]
 }
 
diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/loader/IdlModelParser.java b/smithy-model/src/main/java/software/amazon/smithy/model/loader/IdlModelParser.java index 9ddfd8a4676..42c827e787a 100644 --- a/smithy-model/src/main/java/software/amazon/smithy/model/loader/IdlModelParser.java +++ b/smithy-model/src/main/java/software/amazon/smithy/model/loader/IdlModelParser.java @@ -142,17 +142,23 @@ ModelFile parse() { @Override public void ws() { while (!eof()) { - char c = peek(); - if (c == '/') { - if (peekDocComment()) { - parseDocComment(); - } else { - parseComment(); - } - } else if (!(c == ' ' || c == '\t' || c == '\r' || c == '\n')) { - break; - } else { - skip(); + switch (peek()) { + case '/': + if (peekDocComment()) { + parseDocComment(); + } else { + parseComment(); + } + break; + case ' ': + case '\t': + case '\r': + case '\n': + case ',': + skip(); + break; + default: + return; } } } @@ -192,7 +198,6 @@ private void parseControlSection() { .build()); } - br(); ws(); } } @@ -227,7 +232,6 @@ private void parseMetadataSection() { expect('='); ws(); modelFile.putMetadata(key, IdlNodeParser.parseNode(this)); - br(); ws(); } } @@ -249,11 +253,10 @@ private void parseShapeSection() { int start = position(); ParserUtils.consumeNamespace(this); modelFile.setNamespace(sliceFrom(start)); - - br(); // Clear out any erroneous documentation comments. clearPendingDocs(); ws(); + parseUseSection(); parseShapeStatements(); } else if (!eof()) { @@ -278,7 +281,6 @@ private void parseUseSection() { expect('#'); ParserUtils.consumeIdentifier(this); String lexeme = sliceFrom(start); - br(); // Clear out any erroneous documentation comments. clearPendingDocs(); ws(); @@ -422,7 +424,7 @@ private void parseShape(List traits) { addTraits(id, traits); clearPendingDocs(); - br(); + ws(); } private ShapeId parseShapeName() { @@ -451,31 +453,24 @@ private void parseMembers(ShapeId id, Set requiredMembers) { ws(); expect('{'); - // Don't keep any previous state of captured doc comments when - // parsing members. - clearPendingDocs(); ws(); - if (peek() != '}') { - parseMember(id, requiredMembers, definedMembers, remaining); - while (!eof()) { - ws(); - if (peek() == ',') { - expect(','); - // A comma clears out any previously captured documentation - // comments that may have been found when parsing the member. - clearPendingDocs(); - ws(); - if (peek() == '}') { - // Trailing comma: "," "}" - break; - } - parseMember(id, requiredMembers, definedMembers, remaining); - } else { - // Assume '}'; break to enforce. - break; - } + while (!eof()) { + if (peek() == '}') { + break; } + + parseMember(id, requiredMembers, definedMembers, remaining); + + // Clears out any previously captured documentation + // comments that may have been found when parsing the member. + clearPendingDocs(); + + ws(); + } + + if (eof()) { + expect('}'); } if (!remaining.isEmpty()) { @@ -486,7 +481,7 @@ private void parseMembers(ShapeId id, Set requiredMembers) { expect('}'); } - private String parseMember(ShapeId parent, Set required, Set defined, Set remaining) { + private void parseMember(ShapeId parent, Set required, Set defined, Set remaining) { // Parse optional member traits. List memberTraits = parseDocsAndTraits(); SourceLocation memberLocation = currentLocation(); @@ -514,8 +509,6 @@ private String parseMember(ShapeId parent, Set required, Set def modelFile.onShape(memberBuilder); modelFile.addForwardReference(target, memberBuilder::target); addTraits(memberId, memberTraits); - - return memberName; } private void parseMapStatement(ShapeId id, SourceLocation location) { @@ -662,7 +655,6 @@ private void parseApplyStatement() { // Clear out any errantly captured pending docs. clearPendingDocs(); - br(); ws(); } @@ -746,19 +738,16 @@ private String peekDebugMessage() { break; } } - return result.toString(); - } - - // Take two characters for context. - for (int i = 0; i < 2; i++) { - char peek = peek(i); - if (peek == Character.MIN_VALUE) { - result.append("[EOF]"); - break; + } else { + // Take two characters for context. + for (int i = 0; i < 2; i++) { + char peek = peek(i); + if (peek != Character.MIN_VALUE) { + result.append(peek); + } } - result.append(peek); } - return result.toString(); + return result.length() == 0 ? "[EOF]" : result.toString(); } } diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/loader/IdlNodeParser.java b/smithy-model/src/main/java/software/amazon/smithy/model/loader/IdlNodeParser.java index f8acef0c9bc..3794161955e 100644 --- a/smithy-model/src/main/java/software/amazon/smithy/model/loader/IdlNodeParser.java +++ b/smithy-model/src/main/java/software/amazon/smithy/model/loader/IdlNodeParser.java @@ -143,12 +143,6 @@ static ObjectNode parseObjectNode(IdlModelParser parser, String parent) { throw parser.syntax("Duplicate member of " + parent + ": '" + keyNode.getValue() + '\''); } parser.ws(); - if (parser.peek() == ',') { - parser.skip(); - parser.ws(); - } else { - break; - } } } @@ -179,12 +173,6 @@ private static ArrayNode parseArrayNode(IdlModelParser parser) { } else { items.add(parseNode(parser)); parser.ws(); - if (parser.peek() == ',') { - parser.skip(); - parser.ws(); - } else { - break; - } } } diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/loader/IdlTraitParser.java b/smithy-model/src/main/java/software/amazon/smithy/model/loader/IdlTraitParser.java index a7dda2041e5..f911cac3738 100644 --- a/smithy-model/src/main/java/software/amazon/smithy/model/loader/IdlTraitParser.java +++ b/smithy-model/src/main/java/software/amazon/smithy/model/loader/IdlTraitParser.java @@ -127,11 +127,6 @@ private static ObjectNode parseStructuredTrait(IdlModelParser parser, StringNode parser.ws(); while (!parser.eof() && parser.peek() != ')') { - parser.expect(','); - parser.ws(); - if (parser.peek() == ')') { - break; - } char c = parser.peek(); if (ParserUtils.isIdentifierStart(c) || c == '"') { parseTraitStructureKvp(parser, entries); diff --git a/smithy-model/src/test/java/software/amazon/smithy/model/loader/ValidSmithyModelLoaderRunnerTest.java b/smithy-model/src/test/java/software/amazon/smithy/model/loader/ValidSmithyModelLoaderRunnerTest.java index c6743ac3583..d825731396f 100644 --- a/smithy-model/src/test/java/software/amazon/smithy/model/loader/ValidSmithyModelLoaderRunnerTest.java +++ b/smithy-model/src/test/java/software/amazon/smithy/model/loader/ValidSmithyModelLoaderRunnerTest.java @@ -75,11 +75,13 @@ public void parserRunnerTest(String file) { } if (!result.equals(expected)) { + ModelSerializer serializer = ModelSerializer.builder().build(); throw new IllegalStateException(String.format( - "Result did not match the expected model for %s.\nResult:\n\n%s\n\nExpected:\n\n%s", + "Result did not match the expected model for %s.\nResult:\n\n%s\n\nExpected:\n\n%s\r\nDiff: %s", file, formatModel(result), - formatModel(expected))); + formatModel(expected), + Node.diff(serializer.serialize(result), serializer.serialize(expected)))); } } diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/errorfiles/loader/dupe-trait-member-names.errors b/smithy-model/src/test/resources/software/amazon/smithy/model/errorfiles/loader/dupe-trait-member-names.errors index fac09bb1f72..dcf7880ff3f 100644 --- a/smithy-model/src/test/resources/software/amazon/smithy/model/errorfiles/loader/dupe-trait-member-names.errors +++ b/smithy-model/src/test/resources/software/amazon/smithy/model/errorfiles/loader/dupe-trait-member-names.errors @@ -1 +1 @@ -[ERROR] -: Parse error at line 5, column 19 near `, | Model +[ERROR] -: Parse error at line 6, column 1 | Model diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/annotation-unclosed-list1.smithy b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/annotation-unclosed-list1.smithy index fa8ca767a1d..2232a3c7b1d 100644 --- a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/annotation-unclosed-list1.smithy +++ b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/annotation-unclosed-list1.smithy @@ -1,4 +1,4 @@ -// Parse error at line 4, column 1 near `string`: Expected: ']', but found 's' +// Parse error at line 5, column 1 near `[EOF]`: Expected: ']', but found '[EOF]' | Model namespace com.foo @tags(["foo", "bar" string MyString diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/annotation-unclosed-list2.smithy b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/annotation-unclosed-list2.smithy index d96babdd243..75d5edb8dd7 100644 --- a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/annotation-unclosed-list2.smithy +++ b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/annotation-unclosed-list2.smithy @@ -1,4 +1,4 @@ -// Parse error at line 4, column 8 near `MyString`: Expected: ']', but found 'M' +// Parse error at line 5, column 1 near `[EOF]`: Expected: ']', but found '[EOF]' namespace com.foo @tags(["foo", "bar", string MyString diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/annotation-unclosed-list3.smithy b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/annotation-unclosed-list3.smithy index 95bb574aff9..e28933d9803 100644 --- a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/annotation-unclosed-list3.smithy +++ b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/annotation-unclosed-list3.smithy @@ -1,4 +1,4 @@ -// Parse error at line 4, column 8 near `MyString`: Expected: ']', but found 'M' +// Parse error at line 5, column 1 near `[EOF]`: Expected: ']', but found '[EOF]' namespace com.foo @tags([ string MyString diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/annotation-unclosed-object3.smithy b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/annotation-unclosed-object3.smithy index c74985ddc1f..0e93fd78bee 100644 --- a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/annotation-unclosed-object3.smithy +++ b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/annotation-unclosed-object3.smithy @@ -1,4 +1,4 @@ -// Parse error at line 4, column 8 near `MyString`: Expected: ',', but found 'M' +// Parse error at line 5, column 1 near `[EOF]`: Expected: ':', but found '[EOF]' namespace com.foo @foo(bar: string MyString diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/annotation-unclosed-object4.smithy b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/annotation-unclosed-object4.smithy index b880f1a62a4..c1cbbe0a501 100644 --- a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/annotation-unclosed-object4.smithy +++ b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/annotation-unclosed-object4.smithy @@ -1,4 +1,4 @@ -// Parse error at line 4, column 1 near `string`: Expected: ',', but found 's' +// Parse error at line 4, column 8 near `MyString`: Expected: ':', but found 'M' | Model namespace com.foo @foo(bar: "baz" string MyString diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/apply-requires-newline.smithy b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/apply-requires-newline.smithy deleted file mode 100644 index 0e936945728..00000000000 --- a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/apply-requires-newline.smithy +++ /dev/null @@ -1,4 +0,0 @@ -// Parse error at line 4, column 29 near `string`: Expected a line break, but found 's' | Model -namespace com.foo -string SomeShape -apply SomeShape @deprecated string AnotherString diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/map-requires-newline.smithy b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/map-requires-newline.smithy deleted file mode 100644 index 542520f351b..00000000000 --- a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/map-requires-newline.smithy +++ /dev/null @@ -1,6 +0,0 @@ -// Parse error at line 6, column 3 near `string`: Expected a line break -namespace com.foo -map MyMap { - key: smithy.api#String, - value: smithy.api#String -} string MyString diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/map-unclosed-parameters1.smithy b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/map-unclosed-parameters1.smithy index 5227467efc4..d68680f76fb 100644 --- a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/map-unclosed-parameters1.smithy +++ b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/map-unclosed-parameters1.smithy @@ -1,3 +1,3 @@ -// Parse error at line 4, column 1 near `[EOF]`: Expected a valid identifier character, but found '[EOF]' +// Parse error at line 4, column 1 near `[EOF]`: Expected: '}', but found '[EOF]' namespace com.foo map MyMap { diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/map-unclosed-parameters2.smithy b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/map-unclosed-parameters2.smithy index e041b9fb38b..078e67514bc 100644 --- a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/map-unclosed-parameters2.smithy +++ b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/map-unclosed-parameters2.smithy @@ -1,3 +1,3 @@ -// Parse error at line 4, column 1 near `[EOF]`: Expected a valid identifier character, but found '[EOF]' +// Parse error at line 4, column 1 near ``: Expected: '}', but found '' namespace com.foo map MyMap { key: SomeShape, diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/newline-after-shape.smithy b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/newline-after-shape.smithy deleted file mode 100644 index bc72d43ba4d..00000000000 --- a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/newline-after-shape.smithy +++ /dev/null @@ -1,4 +0,0 @@ -// Parse error at line 4, column 17 near `string`: Expected a line break, but found 's' | Model -namespace com.test - -string MyString string OtherString diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/use/use-requires-newline.smithy b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/use/use-requires-newline.smithy deleted file mode 100644 index 79d4f763055..00000000000 --- a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/invalid/use/use-requires-newline.smithy +++ /dev/null @@ -1,6 +0,0 @@ -// Parse error at line 6, column 24 near `use`: Expected a line break -$version: "1.0" - -namespace foo.baz - -use smithy.example#Foo use smithy.example#Baz diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/valid/newlines-are-not-required.json b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/valid/newlines-are-not-required.json new file mode 100644 index 00000000000..8c531be6e71 --- /dev/null +++ b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/valid/newlines-are-not-required.json @@ -0,0 +1,14 @@ +{ + "smithy": "1.0", + "shapes": { + "smithy.example#MyString": { + "type": "string" + }, + "smithy.example#Foo": { + "type": "structure", + "traits": { + "smithy.api#deprecated": {} + } + } + } +} diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/valid/newlines-are-not-required.smithy b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/valid/newlines-are-not-required.smithy new file mode 100644 index 00000000000..cb333abcc07 --- /dev/null +++ b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/valid/newlines-are-not-required.smithy @@ -0,0 +1 @@ +namespace smithy.example string MyString @deprecated structure Foo {} diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/valid/optional-commas.json b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/valid/optional-commas.json new file mode 100644 index 00000000000..61d7bb38930 --- /dev/null +++ b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/valid/optional-commas.json @@ -0,0 +1,260 @@ +{ + "smithy": "1.0", + "shapes": { + "example.weather#Weather": { + "type": "service", + "version": "2006-03-01", + "operations": [ + { + "target": "example.weather#GetCurrentTime" + } + ], + "resources": [ + { + "target": "example.weather#City" + } + ], + "traits": { + "smithy.api#documentation": "Provides weather forecasts.", + "smithy.api#paginated": { + "inputToken": "nextToken", + "outputToken": "nextToken", + "pageSize": "pageSize" + } + } + }, + "example.weather#City": { + "type": "resource", + "identifiers": { + "cityId": { + "target": "example.weather#CityId" + } + }, + "read": { + "target": "example.weather#GetCity" + }, + "list": { + "target": "example.weather#ListCities" + }, + "resources": [ + { + "target": "example.weather#Forecast" + } + ] + }, + "example.weather#CityCoordinates": { + "type": "structure", + "members": { + "latitude": { + "target": "smithy.api#Float", + "traits": { + "smithy.api#required": {} + } + }, + "longitude": { + "target": "smithy.api#Float", + "traits": { + "smithy.api#required": {} + } + } + } + }, + "example.weather#CityId": { + "type": "string", + "traits": { + "smithy.api#pattern": "^[A-Za-z0-9 ]+$" + } + }, + "example.weather#CitySummaries": { + "type": "list", + "member": { + "target": "example.weather#CitySummary" + } + }, + "example.weather#CitySummary": { + "type": "structure", + "members": { + "cityId": { + "target": "example.weather#CityId", + "traits": { + "smithy.api#required": {} + } + }, + "name": { + "target": "smithy.api#String", + "traits": { + "smithy.api#required": {} + } + } + }, + "traits": { + "smithy.api#references": [ + { + "resource": "example.weather#City" + } + ] + } + }, + "example.weather#Forecast": { + "type": "resource", + "identifiers": { + "cityId": { + "target": "example.weather#CityId" + } + }, + "read": { + "target": "example.weather#GetForecast" + } + }, + "example.weather#GetCity": { + "type": "operation", + "input": { + "target": "example.weather#GetCityInput" + }, + "output": { + "target": "example.weather#GetCityOutput" + }, + "errors": [ + { + "target": "example.weather#NoSuchResource" + } + ], + "traits": { + "smithy.api#readonly": {} + } + }, + "example.weather#GetCityInput": { + "type": "structure", + "members": { + "cityId": { + "target": "example.weather#CityId", + "traits": { + "smithy.api#required": {} + } + } + } + }, + "example.weather#GetCityOutput": { + "type": "structure", + "members": { + "name": { + "target": "smithy.api#String", + "traits": { + "smithy.api#required": {} + } + }, + "coordinates": { + "target": "example.weather#CityCoordinates", + "traits": { + "smithy.api#required": {} + } + } + } + }, + "example.weather#GetCurrentTime": { + "type": "operation", + "output": { + "target": "example.weather#GetCurrentTimeOutput" + }, + "traits": { + "smithy.api#readonly": {} + } + }, + "example.weather#GetCurrentTimeOutput": { + "type": "structure", + "members": { + "time": { + "target": "smithy.api#Timestamp", + "traits": { + "smithy.api#required": {} + } + } + } + }, + "example.weather#GetForecast": { + "type": "operation", + "input": { + "target": "example.weather#GetForecastInput" + }, + "output": { + "target": "example.weather#GetForecastOutput" + }, + "traits": { + "smithy.api#readonly": {} + } + }, + "example.weather#GetForecastInput": { + "type": "structure", + "members": { + "cityId": { + "target": "example.weather#CityId", + "traits": { + "smithy.api#required": {} + } + } + } + }, + "example.weather#GetForecastOutput": { + "type": "structure", + "members": { + "chanceOfRain": { + "target": "smithy.api#Float" + } + } + }, + "example.weather#ListCities": { + "type": "operation", + "input": { + "target": "example.weather#ListCitiesInput" + }, + "output": { + "target": "example.weather#ListCitiesOutput" + }, + "traits": { + "smithy.api#paginated": { + "items": "items" + }, + "smithy.api#readonly": {} + } + }, + "example.weather#ListCitiesInput": { + "type": "structure", + "members": { + "nextToken": { + "target": "smithy.api#String" + }, + "pageSize": { + "target": "smithy.api#Integer" + } + } + }, + "example.weather#ListCitiesOutput": { + "type": "structure", + "members": { + "nextToken": { + "target": "smithy.api#String" + }, + "items": { + "target": "example.weather#CitySummaries", + "traits": { + "smithy.api#required": {} + } + } + } + }, + "example.weather#NoSuchResource": { + "type": "structure", + "members": { + "resourceType": { + "target": "smithy.api#String", + "traits": { + "smithy.api#required": {} + } + } + }, + "traits": { + "smithy.api#error": "client" + } + } + } +} diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/valid/optional-commas.smithy b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/valid/optional-commas.smithy new file mode 100644 index 00000000000..af770a08455 --- /dev/null +++ b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/valid/optional-commas.smithy @@ -0,0 +1,136 @@ +namespace example.weather + +// Commas are whitespace. +,,,,,, + +/// Provides weather forecasts. +@paginated( + inputToken: "nextToken" + outputToken: "nextToken" + pageSize: "pageSize" +) +service Weather { + version: "2006-03-01" + resources: [City] + operations: [GetCurrentTime] +} + +resource City { + identifiers: { cityId: CityId } + read: GetCity + list: ListCities + resources: [Forecast] +} + +resource Forecast { + identifiers: { cityId: CityId } + read: GetForecast +} + +// "pattern" is a trait. +@pattern("^[A-Za-z0-9 ]+$") +string CityId + +@readonly +operation GetCity { + input: GetCityInput + output: GetCityOutput + errors: [NoSuchResource] +} + +structure GetCityInput { + // "cityId" provides the identifier for the resource and + // has to be marked as required. + @required + cityId: CityId +} + +structure GetCityOutput { + // "required" is used on output to indicate if the service + // will always provide a value for the member. + @required + name: String + + @required + coordinates: CityCoordinates +} + +// This structure is nested within GetCityOutput. +structure CityCoordinates { + @required + latitude: Float + + @required + longitude: Float +} + +// "error" is a trait that is used to specialize +// a structure as an error. +@error("client") +structure NoSuchResource { + @required + resourceType: String +} + +// The paginated trait indicates that the operation may +// return truncated results. +@readonly +@paginated(items: "items") +operation ListCities { + input: ListCitiesInput + output: ListCitiesOutput +} + +structure ListCitiesInput { + nextToken: String + pageSize: Integer +} + +structure ListCitiesOutput { + nextToken: String + + @required + items: CitySummaries +} + +// CitySummaries is a list of CitySummary structures. +list CitySummaries { + member: CitySummary +} + +// CitySummary contains a reference to a City. +@references([{resource: City}]) +structure CitySummary { + @required + cityId: CityId + + @required + name: String +} + +@readonly +operation GetCurrentTime { + output: GetCurrentTimeOutput +} + +structure GetCurrentTimeOutput { + @required + time: Timestamp +} + +@readonly +operation GetForecast { + input: GetForecastInput + output: GetForecastOutput +} + +// "cityId" provides the only identifier for the resource since +// a Forecast doesn't have its own. +structure GetForecastInput { + @required + cityId: CityId +} + +structure GetForecastOutput { + chanceOfRain: Float +} diff --git a/smithy-utils/src/main/java/software/amazon/smithy/utils/SimpleParser.java b/smithy-utils/src/main/java/software/amazon/smithy/utils/SimpleParser.java index a7049346d38..789efca1072 100644 --- a/smithy-utils/src/main/java/software/amazon/smithy/utils/SimpleParser.java +++ b/smithy-utils/src/main/java/software/amazon/smithy/utils/SimpleParser.java @@ -206,29 +206,28 @@ public RuntimeException syntax(String message) { * Skip 0 or more whitespace characters (that is, ' ', '\t', '\r', and '\n'). */ public void ws() { - while (!eof()) { - char c = peek(); - if (!(c == ' ' || c == '\t' || c == '\r' || c == '\n')) { - break; - } else { - skip(); - } + while (!eof() && isWhitespace(peek())) { + skip(); } } + private boolean isWhitespace(char c) { + return c == ' ' || c == '\t' || c == '\r' || c == '\n'; + } + /** * Skip 0 or more spaces (that is, ' ' and '\t'). */ public void sp() { - while (!eof()) { - char c = peek(); - if (!(c == ' ' || c == '\t')) { - break; - } + while (!eof() && isSpace(peek())) { skip(); } } + private boolean isSpace(char c) { + return c == ' ' || c == '\t'; + } + /** * Skips spaces then expects that the next character is either the end of * the expression or a line break (\n, \r\n, or \r).