From 45a2540b9bd48aadb14cdf6f3beb9b387c711f45 Mon Sep 17 00:00:00 2001 From: George Fu Date: Fri, 29 Aug 2025 16:51:05 -0400 Subject: [PATCH 1/2] wip schema bucketing --- .../src/commands/EmptyInputOutputCommand.ts | 2 +- .../src/commands/Float16Command.ts | 2 +- .../src/commands/FractionalSecondsCommand.ts | 2 +- .../src/commands/GreetingWithErrorsCommand.ts | 2 +- .../src/commands/NoInputOutputCommand.ts | 2 +- .../commands/OperationWithDefaultsCommand.ts | 2 +- .../commands/OptionalInputOutputCommand.ts | 2 +- .../src/commands/RecursiveShapesCommand.ts | 2 +- .../src/commands/RpcV2CborDenseMapsCommand.ts | 2 +- .../src/commands/RpcV2CborListsCommand.ts | 2 +- .../commands/RpcV2CborSparseMapsCommand.ts | 2 +- .../commands/SimpleScalarPropertiesCommand.ts | 2 +- .../commands/SparseNullsOperationCommand.ts | 2 +- .../src/schemas/{schemas.ts => schemas_0.ts} | 291 ++++++++---------- .../src/schemas/schemas_1_EmptyInputOutput.ts | 14 + .../schemas/schemas_2_FractionalSeconds.ts | 14 + .../src/schemas/schemas_3_.ts | 14 + .../src/schemas/schemas_4_NoInputOutput.ts | 13 + .../typescript/codegen/CommandGenerator.java | 4 +- .../codegen/schema/SchemaGenerator.java | 179 ++++++++--- .../codegen/schema/ShapeTreeOrganizer.java | 264 ++++++++++++++++ .../typescript/codegen/util/StringStore.java | 40 ++- 22 files changed, 638 insertions(+), 221 deletions(-) rename private/smithy-rpcv2-cbor-schema/src/schemas/{schemas.ts => schemas_0.ts} (56%) create mode 100644 private/smithy-rpcv2-cbor-schema/src/schemas/schemas_1_EmptyInputOutput.ts create mode 100644 private/smithy-rpcv2-cbor-schema/src/schemas/schemas_2_FractionalSeconds.ts create mode 100644 private/smithy-rpcv2-cbor-schema/src/schemas/schemas_3_.ts create mode 100644 private/smithy-rpcv2-cbor-schema/src/schemas/schemas_4_NoInputOutput.ts create mode 100644 smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/schema/ShapeTreeOrganizer.java diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/EmptyInputOutputCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/EmptyInputOutputCommand.ts index 8bf4d3e4bc7..8117e457c5a 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/EmptyInputOutputCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/EmptyInputOutputCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { EmptyStructure } from "../models/models_0"; -import { EmptyInputOutput } from "../schemas/schemas"; +import { EmptyInputOutput } from "../schemas/schemas_1_EmptyInputOutput"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/Float16Command.ts b/private/smithy-rpcv2-cbor-schema/src/commands/Float16Command.ts index 36519027a5c..3071dc7b428 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/Float16Command.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/Float16Command.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { Float16Output } from "../models/models_0"; -import { Float16 } from "../schemas/schemas"; +import { Float16 } from "../schemas/schemas_3_"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/FractionalSecondsCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/FractionalSecondsCommand.ts index bdb8a27f3a7..983f166c7cb 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/FractionalSecondsCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/FractionalSecondsCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { FractionalSecondsOutput } from "../models/models_0"; -import { FractionalSeconds } from "../schemas/schemas"; +import { FractionalSeconds } from "../schemas/schemas_2_FractionalSeconds"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/GreetingWithErrorsCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/GreetingWithErrorsCommand.ts index 2bdd8ab5295..6f10b204ea9 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/GreetingWithErrorsCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/GreetingWithErrorsCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { GreetingWithErrorsOutput } from "../models/models_0"; -import { GreetingWithErrors } from "../schemas/schemas"; +import { GreetingWithErrors } from "../schemas/schemas_0"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/NoInputOutputCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/NoInputOutputCommand.ts index 1f32c1beab1..a37b89742b0 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/NoInputOutputCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/NoInputOutputCommand.ts @@ -1,7 +1,7 @@ // smithy-typescript generated code import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; -import { NoInputOutput } from "../schemas/schemas"; +import { NoInputOutput } from "../schemas/schemas_4_NoInputOutput"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/OperationWithDefaultsCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/OperationWithDefaultsCommand.ts index 5b20c18c592..9f4774bb5f1 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/OperationWithDefaultsCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/OperationWithDefaultsCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { OperationWithDefaultsInput, OperationWithDefaultsOutput } from "../models/models_0"; -import { OperationWithDefaults } from "../schemas/schemas"; +import { OperationWithDefaults } from "../schemas/schemas_0"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/OptionalInputOutputCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/OptionalInputOutputCommand.ts index 87a512bda9d..d25861d66f6 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/OptionalInputOutputCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/OptionalInputOutputCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { SimpleStructure } from "../models/models_0"; -import { OptionalInputOutput } from "../schemas/schemas"; +import { OptionalInputOutput } from "../schemas/schemas_0"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/RecursiveShapesCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/RecursiveShapesCommand.ts index 8ee991482ff..764698db544 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/RecursiveShapesCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/RecursiveShapesCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { RecursiveShapesInputOutput } from "../models/models_0"; -import { RecursiveShapes } from "../schemas/schemas"; +import { RecursiveShapes } from "../schemas/schemas_0"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborDenseMapsCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborDenseMapsCommand.ts index c7e6686b358..1ecb7c572c8 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborDenseMapsCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborDenseMapsCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { RpcV2CborDenseMapsInputOutput } from "../models/models_0"; -import { RpcV2CborDenseMaps } from "../schemas/schemas"; +import { RpcV2CborDenseMaps } from "../schemas/schemas_0"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborListsCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborListsCommand.ts index 5b1ad6cf1ca..b86a40455f1 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborListsCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborListsCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { RpcV2CborListInputOutput } from "../models/models_0"; -import { RpcV2CborLists } from "../schemas/schemas"; +import { RpcV2CborLists } from "../schemas/schemas_0"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborSparseMapsCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborSparseMapsCommand.ts index 69ffd3ff2f8..1705ee4fca7 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborSparseMapsCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborSparseMapsCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { RpcV2CborSparseMapsInputOutput } from "../models/models_0"; -import { RpcV2CborSparseMaps } from "../schemas/schemas"; +import { RpcV2CborSparseMaps } from "../schemas/schemas_0"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/SimpleScalarPropertiesCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/SimpleScalarPropertiesCommand.ts index 9a0244e3ff8..229c21f0bdd 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/SimpleScalarPropertiesCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/SimpleScalarPropertiesCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { SimpleScalarStructure } from "../models/models_0"; -import { SimpleScalarProperties } from "../schemas/schemas"; +import { SimpleScalarProperties } from "../schemas/schemas_0"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/SparseNullsOperationCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/SparseNullsOperationCommand.ts index 56696a232bf..fc6dbbafbdb 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/SparseNullsOperationCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/SparseNullsOperationCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { SparseNullsOperationInputOutput } from "../models/models_0"; -import { SparseNullsOperation } from "../schemas/schemas"; +import { SparseNullsOperation } from "../schemas/schemas_0"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/schemas/schemas.ts b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_0.ts similarity index 56% rename from private/smithy-rpcv2-cbor-schema/src/schemas/schemas.ts rename to private/smithy-rpcv2-cbor-schema/src/schemas/schemas_0.ts index a35afb55e51..89da2306ee0 100644 --- a/private/smithy-rpcv2-cbor-schema/src/schemas/schemas.ts +++ b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_0.ts @@ -1,133 +1,133 @@ -const _CE = "ComplexError"; -const _CNED = "ComplexNestedErrorData"; -const _COD = "ClientOptionalDefaults"; -const _D = "Defaults"; -const _DSM = "DenseSetMap"; -const _DSMe = "DenseStructMap"; -const _EIO = "EmptyInputOutput"; -const _ES = "EmptyStructure"; -const _F = "Foo"; -const _FO = "Float16Output"; -const _FS = "FractionalSeconds"; -const _FSO = "FractionalSecondsOutput"; -const _Fl = "Float16"; -const _GS = "GreetingStruct"; -const _GWE = "GreetingWithErrors"; -const _GWEO = "GreetingWithErrorsOutput"; -const _IG = "InvalidGreeting"; -const _M = "Message"; -const _N = "Nested"; -const _NIO = "NoInputOutput"; -const _NSL = "NestedStringList"; -const _OIO = "OptionalInputOutput"; -const _OWD = "OperationWithDefaults"; -const _OWDI = "OperationWithDefaultsInput"; -const _OWDO = "OperationWithDefaultsOutput"; -const _RS = "RecursiveShapes"; -const _RSIO = "RecursiveShapesInputOutput"; -const _RSION = "RecursiveShapesInputOutputNested1"; -const _RSIONe = "RecursiveShapesInputOutputNested2"; -const _RVCDM = "RpcV2CborDenseMaps"; -const _RVCDMIO = "RpcV2CborDenseMapsInputOutput"; -const _RVCL = "RpcV2CborLists"; -const _RVCLIO = "RpcV2CborListInputOutput"; -const _RVCSM = "RpcV2CborSparseMaps"; -const _RVCSMIO = "RpcV2CborSparseMapsInputOutput"; -const _SBM = "SparseBooleanMap"; -const _SL = "StructureList"; -const _SLM = "StructureListMember"; -const _SNM = "SparseNumberMap"; -const _SNO = "SparseNullsOperation"; -const _SNOIO = "SparseNullsOperationInputOutput"; -const _SS = "SimpleStructure"; -const _SSL = "SparseStringList"; -const _SSM = "SparseSetMap"; -const _SSMp = "SparseStructMap"; -const _SSMpa = "SparseStringMap"; -const _SSP = "SimpleScalarProperties"; -const _SSS = "SimpleScalarStructure"; -const _TL = "TopLevel"; -const _VE = "ValidationException"; -const _VEF = "ValidationExceptionField"; -const _VEFL = "ValidationExceptionFieldList"; -const _a = "a"; -const _b = "bar"; -const _bL = "booleanList"; -const _bLl = "blobList"; -const _bV = "byteValue"; -const _bVl = "blobValue"; -const _b_ = "b"; -const _c = "client"; -const _cOD = "clientOptionalDefaults"; -const _d = "datetime"; -const _dB = "defaultBoolean"; -const _dBM = "denseBooleanMap"; -const _dBe = "defaultBlob"; -const _dBef = "defaultByte"; -const _dD = "defaultDouble"; -const _dE = "defaultEnum"; -const _dF = "defaultFloat"; -const _dI = "defaultInteger"; -const _dIE = "defaultIntEnum"; -const _dL = "defaultList"; -const _dLe = "defaultLong"; -const _dM = "defaultMap"; -const _dNM = "denseNumberMap"; -const _dS = "defaultString"; -const _dSM = "denseStructMap"; -const _dSMe = "denseStringMap"; -const _dSMen = "denseSetMap"; -const _dSe = "defaultShort"; -const _dT = "defaultTimestamp"; -const _dV = "doubleValue"; -const _de = "defaults"; -const _e = "error"; -const _eB = "emptyBlob"; -const _eL = "enumList"; -const _eS = "emptyString"; -const _f = "foo"; -const _fB = "falseBoolean"; -const _fBV = "falseBooleanValue"; -const _fL = "fieldList"; -const _fV = "floatValue"; -const _g = "greeting"; -const _h = "hi"; -const _iEL = "intEnumList"; -const _iL = "integerList"; -const _iV = "integerValue"; -const _lV = "longValue"; -const _m = "message"; -const _me = "member"; -const _n = "nested"; -const _nSL = "nestedStringList"; -const _oTLD = "otherTopLevelDefault"; -const _p = "path"; -const _rM = "recursiveMember"; -const _s = "sparse"; -const _sBM = "sparseBooleanMap"; -const _sL = "stringList"; -const _sLt = "structureList"; -const _sNM = "sparseNumberMap"; -const _sS = "stringSet"; -const _sSL = "sparseStringList"; -const _sSM = "sparseStructMap"; -const _sSMp = "sparseStringMap"; -const _sSMpa = "sparseSetMap"; -const _sV = "shortValue"; -const _sVt = "stringValue"; -const _tBV = "trueBooleanValue"; -const _tL = "timestampList"; -const _tLD = "topLevelDefault"; -const _v = "value"; -const _zB = "zeroByte"; -const _zD = "zeroDouble"; -const _zF = "zeroFloat"; -const _zI = "zeroInteger"; -const _zL = "zeroLong"; -const _zS = "zeroShort"; -const n0 = "smithy.framework"; -const n1 = "smithy.protocoltests.rpcv2Cbor"; -const n2 = "smithy.protocoltests.shared"; +export const _CE = "ComplexError"; +export const _CNED = "ComplexNestedErrorData"; +export const _COD = "ClientOptionalDefaults"; +export const _D = "Defaults"; +export const _DSM = "DenseSetMap"; +export const _DSMe = "DenseStructMap"; +export const _EIO = "EmptyInputOutput"; +export const _ES = "EmptyStructure"; +export const _F = "Foo"; +export const _FO = "Float16Output"; +export const _FS = "FractionalSeconds"; +export const _FSO = "FractionalSecondsOutput"; +export const _Fl = "Float16"; +export const _GS = "GreetingStruct"; +export const _GWE = "GreetingWithErrors"; +export const _GWEO = "GreetingWithErrorsOutput"; +export const _IG = "InvalidGreeting"; +export const _M = "Message"; +export const _N = "Nested"; +export const _NIO = "NoInputOutput"; +export const _NSL = "NestedStringList"; +export const _OIO = "OptionalInputOutput"; +export const _OWD = "OperationWithDefaults"; +export const _OWDI = "OperationWithDefaultsInput"; +export const _OWDO = "OperationWithDefaultsOutput"; +export const _RS = "RecursiveShapes"; +export const _RSIO = "RecursiveShapesInputOutput"; +export const _RSION = "RecursiveShapesInputOutputNested1"; +export const _RSIONe = "RecursiveShapesInputOutputNested2"; +export const _RVCDM = "RpcV2CborDenseMaps"; +export const _RVCDMIO = "RpcV2CborDenseMapsInputOutput"; +export const _RVCL = "RpcV2CborLists"; +export const _RVCLIO = "RpcV2CborListInputOutput"; +export const _RVCSM = "RpcV2CborSparseMaps"; +export const _RVCSMIO = "RpcV2CborSparseMapsInputOutput"; +export const _SBM = "SparseBooleanMap"; +export const _SL = "StructureList"; +export const _SLM = "StructureListMember"; +export const _SNM = "SparseNumberMap"; +export const _SNO = "SparseNullsOperation"; +export const _SNOIO = "SparseNullsOperationInputOutput"; +export const _SS = "SimpleStructure"; +export const _SSL = "SparseStringList"; +export const _SSM = "SparseSetMap"; +export const _SSMp = "SparseStructMap"; +export const _SSMpa = "SparseStringMap"; +export const _SSP = "SimpleScalarProperties"; +export const _SSS = "SimpleScalarStructure"; +export const _TL = "TopLevel"; +export const _VE = "ValidationException"; +export const _VEF = "ValidationExceptionField"; +export const _VEFL = "ValidationExceptionFieldList"; +export const _a = "a"; +export const _b = "bar"; +export const _bL = "booleanList"; +export const _bLl = "blobList"; +export const _bV = "byteValue"; +export const _bVl = "blobValue"; +export const _b_ = "b"; +export const _c = "client"; +export const _cOD = "clientOptionalDefaults"; +export const _d = "datetime"; +export const _dB = "defaultBoolean"; +export const _dBM = "denseBooleanMap"; +export const _dBe = "defaultBlob"; +export const _dBef = "defaultByte"; +export const _dD = "defaultDouble"; +export const _dE = "defaultEnum"; +export const _dF = "defaultFloat"; +export const _dI = "defaultInteger"; +export const _dIE = "defaultIntEnum"; +export const _dL = "defaultList"; +export const _dLe = "defaultLong"; +export const _dM = "defaultMap"; +export const _dNM = "denseNumberMap"; +export const _dS = "defaultString"; +export const _dSM = "denseStructMap"; +export const _dSMe = "denseStringMap"; +export const _dSMen = "denseSetMap"; +export const _dSe = "defaultShort"; +export const _dT = "defaultTimestamp"; +export const _dV = "doubleValue"; +export const _de = "defaults"; +export const _e = "error"; +export const _eB = "emptyBlob"; +export const _eL = "enumList"; +export const _eS = "emptyString"; +export const _f = "foo"; +export const _fB = "falseBoolean"; +export const _fBV = "falseBooleanValue"; +export const _fL = "fieldList"; +export const _fV = "floatValue"; +export const _g = "greeting"; +export const _h = "hi"; +export const _iEL = "intEnumList"; +export const _iL = "integerList"; +export const _iV = "integerValue"; +export const _lV = "longValue"; +export const _m = "message"; +export const _me = "member"; +export const _n = "nested"; +export const _nSL = "nestedStringList"; +export const _oTLD = "otherTopLevelDefault"; +export const _p = "path"; +export const _rM = "recursiveMember"; +export const _s = "sparse"; +export const _sBM = "sparseBooleanMap"; +export const _sL = "stringList"; +export const _sLt = "structureList"; +export const _sNM = "sparseNumberMap"; +export const _sS = "stringSet"; +export const _sSL = "sparseStringList"; +export const _sSM = "sparseStructMap"; +export const _sSMp = "sparseStringMap"; +export const _sSMpa = "sparseSetMap"; +export const _sV = "shortValue"; +export const _sVt = "stringValue"; +export const _tBV = "trueBooleanValue"; +export const _tL = "timestampList"; +export const _tLD = "topLevelDefault"; +export const _v = "value"; +export const _zB = "zeroByte"; +export const _zD = "zeroDouble"; +export const _zF = "zeroFloat"; +export const _zI = "zeroInteger"; +export const _zL = "zeroLong"; +export const _zS = "zeroShort"; +export const n0 = "smithy.framework"; +export const n1 = "smithy.protocoltests.rpcv2Cbor"; +export const n2 = "smithy.protocoltests.shared"; // smithy-typescript generated code import { RpcV2ProtocolServiceException as __RpcV2ProtocolServiceException } from "../models/RpcV2ProtocolServiceException"; @@ -198,9 +198,6 @@ export var Defaults = struct( ], [0, 2, 64 | 0, 4, 21, 1, 1, 1, 1, 1, 1, 128 | 0, 0, 1, 0, 2, 21, 1, 1, 1, 1, 1, 1] ); -export var EmptyStructure = struct(n1, _ES, 0, [], []); -export var Float16Output = struct(n1, _FO, 0, [_v], [1]); -export var FractionalSecondsOutput = struct(n1, _FSO, 0, [_d], [5]); export var GreetingWithErrorsOutput = struct(n1, _GWEO, 0, [_g], [0]); export var InvalidGreeting = error( n1, @@ -405,27 +402,6 @@ export var SparseStringMap = map( 0, 0 ); -export var EmptyInputOutput = op( - n1, - _EIO, - 0, - () => EmptyStructure, - () => EmptyStructure -); -export var Float16 = op( - n1, - _Fl, - 0, - () => Unit, - () => Float16Output -); -export var FractionalSeconds = op( - n1, - _FS, - 0, - () => Unit, - () => FractionalSecondsOutput -); export var GreetingWithErrors = op( n1, _GWE, @@ -433,13 +409,6 @@ export var GreetingWithErrors = op( () => Unit, () => GreetingWithErrorsOutput ); -export var NoInputOutput = op( - n1, - _NIO, - 0, - () => Unit, - () => Unit -); export var OperationWithDefaults = op( n1, _OWD, diff --git a/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_1_EmptyInputOutput.ts b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_1_EmptyInputOutput.ts new file mode 100644 index 00000000000..6f08d2ec392 --- /dev/null +++ b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_1_EmptyInputOutput.ts @@ -0,0 +1,14 @@ +// smithy-typescript generated code +import { _EIO, _ES, n1 } from "./schemas_0"; +import { op, struct } from "@smithy/core/schema"; + +/* eslint no-var: 0 */ + +export var EmptyStructure = struct(n1, _ES, 0, [], []); +export var EmptyInputOutput = op( + n1, + _EIO, + 0, + () => EmptyStructure, + () => EmptyStructure +); diff --git a/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_2_FractionalSeconds.ts b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_2_FractionalSeconds.ts new file mode 100644 index 00000000000..bd7028329b2 --- /dev/null +++ b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_2_FractionalSeconds.ts @@ -0,0 +1,14 @@ +// smithy-typescript generated code +import { Unit, _FS, _FSO, _d, n1 } from "./schemas_0"; +import { op, struct } from "@smithy/core/schema"; + +/* eslint no-var: 0 */ + +export var FractionalSecondsOutput = struct(n1, _FSO, 0, [_d], [5]); +export var FractionalSeconds = op( + n1, + _FS, + 0, + () => Unit, + () => FractionalSecondsOutput +); diff --git a/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_3_.ts b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_3_.ts new file mode 100644 index 00000000000..50292ac5bbe --- /dev/null +++ b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_3_.ts @@ -0,0 +1,14 @@ +// smithy-typescript generated code +import { Unit, _FO, _Fl, _v, n1 } from "./schemas_0"; +import { op, struct } from "@smithy/core/schema"; + +/* eslint no-var: 0 */ + +export var Float16Output = struct(n1, _FO, 0, [_v], [1]); +export var Float16 = op( + n1, + _Fl, + 0, + () => Unit, + () => Float16Output +); diff --git a/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_4_NoInputOutput.ts b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_4_NoInputOutput.ts new file mode 100644 index 00000000000..e6488cbaf49 --- /dev/null +++ b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_4_NoInputOutput.ts @@ -0,0 +1,13 @@ +// smithy-typescript generated code +import { Unit, _NIO, n1 } from "./schemas_0"; +import { op } from "@smithy/core/schema"; + +/* eslint no-var: 0 */ + +export var NoInputOutput = op( + n1, + _NIO, + 0, + () => Unit, + () => Unit +); diff --git a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/CommandGenerator.java b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/CommandGenerator.java index dc73f8c2029..e596013d345 100644 --- a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/CommandGenerator.java +++ b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/CommandGenerator.java @@ -61,6 +61,7 @@ import software.amazon.smithy.typescript.codegen.integration.ProtocolGenerator; import software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin; import software.amazon.smithy.typescript.codegen.schema.SchemaGenerationAllowlist; +import software.amazon.smithy.typescript.codegen.schema.ShapeTreeOrganizer; import software.amazon.smithy.typescript.codegen.sections.CommandBodyExtraCodeSection; import software.amazon.smithy.typescript.codegen.sections.CommandConstructorCodeSection; import software.amazon.smithy.typescript.codegen.sections.CommandPropertiesCodeSection; @@ -668,9 +669,10 @@ private void addCommandSpecificPlugins() { } private void writeSchemaSerde() { + ShapeTreeOrganizer shapeTree = ShapeTreeOrganizer.forModel(model); String operationSchema = reservedWords.escape(operation.getId().getName()); writer.addRelativeImport(operationSchema, null, Paths.get( - ".", CodegenUtils.SOURCE_FOLDER, SCHEMAS_FOLDER, "schemas" + ".", CodegenUtils.SOURCE_FOLDER, SCHEMAS_FOLDER, shapeTree.getGroup(operation.getId()) )); writer.write(""" .sc($L)""", diff --git a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/schema/SchemaGenerator.java b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/schema/SchemaGenerator.java index 551c1bff1db..db792ec6ba8 100644 --- a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/schema/SchemaGenerator.java +++ b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/schema/SchemaGenerator.java @@ -5,8 +5,11 @@ package software.amazon.smithy.typescript.codegen.schema; +import java.nio.file.Path; import java.nio.file.Paths; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -24,6 +27,7 @@ import software.amazon.smithy.model.shapes.OperationShape; import software.amazon.smithy.model.shapes.ServiceShape; import software.amazon.smithy.model.shapes.Shape; +import software.amazon.smithy.model.shapes.ShapeId; import software.amazon.smithy.model.shapes.ShapeType; import software.amazon.smithy.model.shapes.StructureShape; import software.amazon.smithy.model.shapes.UnionShape; @@ -49,8 +53,8 @@ public class SchemaGenerator implements Runnable { private final SymbolProvider symbolProvider; private final Model model; private final FileManifest fileManifest; - private final StringStore stringStore = new StringStore(); - private final TypeScriptWriter writer = new TypeScriptWriter(""); + private final StringStore store = new StringStore(); + private final Map writers = new HashMap<>(); private final Set loadShapesVisited = new HashSet<>(); @@ -63,6 +67,7 @@ public class SchemaGenerator implements Runnable { private final Set existsAsSchema = new HashSet<>(); private final Set requiresNamingDeconfliction = new HashSet<>(); + private ShapeTreeOrganizer treeOrganizer; private final ReservedWords reservedWords = new ReservedWordsBuilder() .loadWords(Objects.requireNonNull(TypeScriptClientCodegenPlugin.class.getResource("reserved-words.txt"))) @@ -76,11 +81,6 @@ public SchemaGenerator(Model model, elision = SchemaReferenceIndex.of(model); this.settings = settings; this.symbolProvider = symbolProvider; - writer.write( - """ - /* eslint no-var: 0 */ - """ - ); } /** @@ -88,6 +88,7 @@ public SchemaGenerator(Model model, */ @Override public void run() { + treeOrganizer = ShapeTreeOrganizer.forModel(model); for (ServiceShape service : model.getServiceShapes()) { if (!SchemaGenerationAllowlist.allows(service.getId(), settings)) { return; @@ -116,11 +117,40 @@ public void run() { unionShapes.forEach(this::writeUnionSchema); operationShapes.forEach(this::writeOperationSchema); - String stringVariables = stringStore.flushVariableDeclarationCode(); - fileManifest.writeFile( - Paths.get(CodegenUtils.SOURCE_FOLDER, SCHEMAS_FOLDER, "schemas.ts").toString(), - stringVariables + "\n" + writer - ); + String stringConstants = store.flushVariableDeclarationCode() + .replaceAll("const ", "export const "); + + for (Map.Entry entry : writers.entrySet()) { + String group = entry.getKey(); + TypeScriptWriter writer = entry.getValue(); + + boolean hasContent = !writer.toString().endsWith("/* eslint no-var: 0 */\n"); + if (hasContent) { + if (group.equals("schemas_0")) { + fileManifest.writeFile( + Paths.get(CodegenUtils.SOURCE_FOLDER, SCHEMAS_FOLDER, group + ".ts").toString(), + stringConstants + "\n" + writer + ); + } else { + fileManifest.writeFile( + Paths.get(CodegenUtils.SOURCE_FOLDER, SCHEMAS_FOLDER, group + ".ts").toString(), + writer.toString() + ); + } + } + } + + treeOrganizer.debug(); + } + + private TypeScriptWriter getWriter(ShapeId shape) { + return writers.computeIfAbsent(treeOrganizer.getGroup(shape), k -> { + TypeScriptWriter typeScriptWriter = new TypeScriptWriter(""); + typeScriptWriter.write(""" + /* eslint no-var: 0 */ + """); + return typeScriptWriter; + }); } /** @@ -201,19 +231,20 @@ private void deconflictSchemaVarNames() { private String getShapeVariableName(Shape shape) { String symbolName = reservedWords.escape(shape.getId().getName()); if (requiresNamingDeconfliction.contains(shape)) { - symbolName += "_" + stringStore.var(shape.getId().getNamespace(), "n"); + symbolName += "_" + checkImportString(shape, shape.getId().getNamespace(), "n"); } return symbolName; } private void writeSimpleSchema(Shape shape) { + TypeScriptWriter writer = getWriter(shape.getId()); if (elision.traits.hasSchemaTraits(shape)) { writer.addImportSubmodule("sim", "sim", TypeScriptDependency.SMITHY_CORE, "/schema"); writer.write(""" export var $L = sim($L, $L, $L,""", getShapeVariableName(shape), - stringStore.var(shape.getId().getNamespace(), "n"), - stringStore.var(shape.getId().getName()), + checkImportString(shape, shape.getId().getNamespace(), "n"), + checkImportString(shape, shape.getId().getName()), resolveSimpleSchema(shape) ); writeTraits(shape); @@ -222,6 +253,7 @@ private void writeSimpleSchema(Shape shape) { } private void writeStructureSchema(StructureShape shape) { + TypeScriptWriter writer = getWriter(shape.getId()); checkedWriteSchema(shape, () -> { String symbolName = reservedWords.escape(shape.getId().getName()); if (shape.hasTrait(ErrorTrait.class)) { @@ -236,8 +268,8 @@ private void writeStructureSchema(StructureShape shape) { export var $L = error($L, $L,""", "", getShapeVariableName(shape), - stringStore.var(shape.getId().getNamespace(), "n"), - stringStore.var(shape.getId().getName()), + checkImportString(shape, shape.getId().getNamespace(), "n"), + checkImportString(shape, shape.getId().getName()), () -> doWithMembers(shape) ); writer.writeInline(",$L", exceptionCtorSymbolName); @@ -248,8 +280,8 @@ private void writeStructureSchema(StructureShape shape) { export var $L = struct($L, $L,""", ");", getShapeVariableName(shape), - stringStore.var(shape.getId().getNamespace(), "n"), - stringStore.var(shape.getId().getName()), + checkImportString(shape, shape.getId().getNamespace(), "n"), + checkImportString(shape, shape.getId().getName()), () -> doWithMembers(shape) ); } @@ -257,6 +289,8 @@ private void writeStructureSchema(StructureShape shape) { } private void writeBaseError() { + TypeScriptWriter writer = writers.get("schemas_0"); + String serviceName = CodegenUtils.getServiceName(settings, model, symbolProvider); String serviceExceptionName = CodegenUtils.getServiceExceptionName(serviceName); String namespace = settings.getService(model).getId().getNamespace(); @@ -279,14 +313,15 @@ private void writeBaseError() { } private void writeUnionSchema(UnionShape shape) { + TypeScriptWriter writer = getWriter(shape.getId()); checkedWriteSchema(shape, () -> { writer.addImportSubmodule("struct", "uni", TypeScriptDependency.SMITHY_CORE, "/schema"); writer.openBlock(""" export var $L = uni($L, $L,""", ");", getShapeVariableName(shape), - stringStore.var(shape.getId().getNamespace(), "n"), - stringStore.var(shape.getId().getName()), + checkImportString(shape, shape.getId().getNamespace(), "n"), + checkImportString(shape, shape.getId().getName()), () -> doWithMembers(shape) ); }); @@ -296,22 +331,26 @@ private void writeUnionSchema(UnionShape shape) { * Handles the member entries for unions/structures. */ private void doWithMembers(Shape shape) { + TypeScriptWriter writer = getWriter(shape.getId()); writeTraits(shape); + // member names. writer.write(", [ "); shape.getAllMembers().forEach((memberName, member) -> { - writer.write("$L,", stringStore.var(memberName)); + writer.write("$L,", checkImportString(shape, memberName)); }); + + // member schemas. writer.write(" ], ["); shape.getAllMembers().forEach((memberName, member) -> { - String ref = resolveSchema(member); + String ref = resolveSchema(shape, member); if (elision.traits.hasSchemaTraits(member)) { writer.openBlock(""" [$L,\s""", "],", ref, () -> { - writeTraits(member); + writeTraitsInContext(shape, member); } ); } else { @@ -322,14 +361,15 @@ private void doWithMembers(Shape shape) { } private void writeListSchema(CollectionShape shape) { + TypeScriptWriter writer = getWriter(shape.getId()); checkedWriteSchema(shape, () -> { writer.addImportSubmodule("list", "list", TypeScriptDependency.SMITHY_CORE, "/schema"); writer.openBlock(""" export var $L = list($L, $L,""", ");", getShapeVariableName(shape), - stringStore.var(shape.getId().getNamespace(), "n"), - stringStore.var(shape.getId().getName()), + checkImportString(shape, shape.getId().getNamespace(), "n"), + checkImportString(shape, shape.getId().getName()), () -> this.doWithMember( shape, shape.getMember() @@ -339,14 +379,15 @@ private void writeListSchema(CollectionShape shape) { } private void writeMapSchema(MapShape shape) { + TypeScriptWriter writer = getWriter(shape.getId()); checkedWriteSchema(shape, () -> { writer.addImportSubmodule("map", "map", TypeScriptDependency.SMITHY_CORE, "/schema"); writer.openBlock(""" export var $L = map($L, $L,""", ");", getShapeVariableName(shape), - stringStore.var(shape.getId().getNamespace(), "n"), - stringStore.var(shape.getId().getName()), + checkImportString(shape, shape.getId().getNamespace(), "n"), + checkImportString(shape, shape.getId().getName()), () -> this.doWithMember( shape, shape.getKey(), @@ -360,15 +401,16 @@ private void writeMapSchema(MapShape shape) { * Write member schema insertion for lists. */ private void doWithMember(Shape shape, MemberShape memberShape) { + TypeScriptWriter writer = getWriter(shape.getId()); writeTraits(shape); - String ref = resolveSchema(memberShape); + String ref = resolveSchema(shape, memberShape); if (elision.traits.hasSchemaTraits(memberShape)) { writer.openBlock( ", [$L, ", "]", ref, () -> { - writeTraits(memberShape); + writeTraitsInContext(shape, memberShape); } ); } else { @@ -380,16 +422,17 @@ private void doWithMember(Shape shape, MemberShape memberShape) { * Write member schema insertion for maps. */ private void doWithMember(Shape shape, MemberShape keyShape, MemberShape memberShape) { + TypeScriptWriter writer = getWriter(shape.getId()); writeTraits(shape); - String keyRef = resolveSchema(keyShape); - String valueRef = resolveSchema(memberShape); + String keyRef = resolveSchema(shape, keyShape); + String valueRef = resolveSchema(shape, memberShape); if (elision.traits.hasSchemaTraits(memberShape) || elision.traits.hasSchemaTraits(keyShape)) { writer.openBlock( ", [$L, ", "]", keyRef, () -> { - writeTraits(keyShape); + writeTraitsInContext(shape, keyShape); } ); writer.openBlock( @@ -397,7 +440,7 @@ private void doWithMember(Shape shape, MemberShape keyShape, MemberShape memberS "]", valueRef, () -> { - writeTraits(memberShape); + writeTraitsInContext(shape, memberShape); } ); } else { @@ -406,15 +449,18 @@ private void doWithMember(Shape shape, MemberShape keyShape, MemberShape memberS } private void writeOperationSchema(OperationShape shape) { + TypeScriptWriter writer = getWriter(shape.getId()); writer.addImportSubmodule("op", "op", TypeScriptDependency.SMITHY_CORE, "/schema"); writer.openBlock(""" export var $L = op($L, $L,""", ");", getShapeVariableName(shape), - stringStore.var(shape.getId().getNamespace(), "n"), - stringStore.var(shape.getId().getName()), + checkImportString(shape, shape.getId().getNamespace(), "n"), + checkImportString(shape, shape.getId().getName()), () -> { writeTraits(shape); + checkImportSchema(shape, model.expectShape(shape.getInputShape())); + checkImportSchema(shape, model.expectShape(shape.getOutputShape())); writer.write(""" , () => $L, () => $L""", getShapeVariableName(model.expectShape(shape.getInputShape())), @@ -425,8 +471,18 @@ private void writeOperationSchema(OperationShape shape) { } private void writeTraits(Shape shape) { + writeTraitsInContext(shape, shape); + } + + private void writeTraitsInContext(Shape context, Shape shape) { + TypeScriptWriter writer = getWriter(context.getId()); + boolean useImportedStrings = !treeOrganizer.isBaseGroup(context); + writer.write( - new SchemaTraitWriter(shape, elision, stringStore).toString() + new SchemaTraitWriter( + shape, elision, + useImportedStrings ? store.useSchemaWriter(writer) : store + ).toString() ); } @@ -434,6 +490,7 @@ private void writeTraits(Shape shape) { * Checks whether ok to write minimized schema. */ private void checkedWriteSchema(Shape shape, Runnable schemaWriteFn) { + TypeScriptWriter writer = getWriter(shape.getId()); if (shape.getId().getNamespace().equals("smithy.api") && shape.getId().getName().equals("Unit")) { // special signal value for operation input/output. @@ -441,7 +498,7 @@ private void checkedWriteSchema(Shape shape, Runnable schemaWriteFn) { export var Unit = "unit" as const; """); } else if (!elision.isReferenceSchema(shape) && !elision.traits.hasSchemaTraits(shape)) { - String sentinel = this.resolveSchema(shape); + String sentinel = this.resolveSchema(model.expectShape(ShapeId.from("smithy.api#Unit")), shape); writer.write( """ @@ -459,7 +516,7 @@ private void checkedWriteSchema(Shape shape, Runnable schemaWriteFn) { * @return generally the symbol name of the target shape, but sometimes a sentinel value for special types like * blob and timestamp. */ - private String resolveSchema(Shape shape) { + private String resolveSchema(Shape context, Shape shape) { MemberShape memberShape = null; if (shape instanceof MemberShape ms) { memberShape = ms; @@ -477,6 +534,10 @@ private String resolveSchema(Shape shape) { } } + if (isReference || hasTraits) { + checkImportSchema(context, shape); + } + return (isReference || hasTraits ? "() => " : "") + getShapeVariableName(shape); } @@ -527,7 +588,8 @@ private String resolveSimpleSchema(Shape shape) { return "19"; } case LIST, SET, MAP -> { - return resolveSimpleSchemaNestedContainer(shape, writer, stringStore); + TypeScriptWriter writer = getWriter(shape.getId()); + return resolveSimpleSchemaNestedContainer(shape, writer); } default -> { // @@ -536,7 +598,7 @@ private String resolveSimpleSchema(Shape shape) { throw new IllegalArgumentException("shape is not simple"); } - private String resolveSimpleSchemaNestedContainer(Shape shape, TypeScriptWriter writer, StringStore stringStore) { + private String resolveSimpleSchemaNestedContainer(Shape shape, TypeScriptWriter writer) { Shape contained; String factory; String sentinel; @@ -566,18 +628,45 @@ private String resolveSimpleSchemaNestedContainer(Shape shape, TypeScriptWriter if (contained.isListShape()) { writer.addImportSubmodule(factory, factory, TypeScriptDependency.SMITHY_CORE, "/schema"); - String schemaVarName = stringStore.var(shape.getId().getName()); - return factory + "(" + stringStore.var(shape.getId().getNamespace(), "n") + ", " + schemaVarName + ", 0, " + String schemaVarName = checkImportString(shape, shape.getId().getName()); + return factory + "(" + + checkImportString(shape, shape.getId().getNamespace(), "n") + ", " + schemaVarName + ", 0, " + keyMemberSchema + this.resolveSimpleSchema(contained) + ")"; } else if (contained.isMapShape()) { writer.addImportSubmodule(factory, factory, TypeScriptDependency.SMITHY_CORE, "/schema"); - String schemaVarName = stringStore.var(shape.getId().getName()); - return factory + "(" + stringStore.var(shape.getId().getNamespace(), "n") + ", " + schemaVarName + ", 0, " + String schemaVarName = checkImportString(shape, shape.getId().getName()); + return factory + "(" + + checkImportString(shape, shape.getId().getNamespace(), "n") + ", " + schemaVarName + ", 0, " + keyMemberSchema + this.resolveSimpleSchema(contained) + ")"; } else { return sentinel + "|" + this.resolveSimpleSchema(contained); } } + + private void checkImportSchema(Shape context, Shape shape) { + String shapeGroup = treeOrganizer.getGroup(shape.getId()); + if (treeOrganizer.different(context, shape)) { + getWriter(context.getId()).addRelativeImport( + getShapeVariableName(shape), null, Path.of("./", shapeGroup) + ); + } + } + + private String checkImportString(Shape context, String fullString) { + return checkImportString(context, fullString, null); + } + + private String checkImportString(Shape context, String fullString, String prefix) { + String var = prefix != null ? store.var(fullString, prefix) : store.var(fullString); + if (!treeOrganizer.isBaseGroup(context)) { + getWriter(context.getId()).addRelativeImport( + var, + null, + Path.of("./schemas_0") + ); + } + return var; + } } diff --git a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/schema/ShapeTreeOrganizer.java b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/schema/ShapeTreeOrganizer.java new file mode 100644 index 00000000000..9e30d102866 --- /dev/null +++ b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/schema/ShapeTreeOrganizer.java @@ -0,0 +1,264 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package software.amazon.smithy.typescript.codegen.schema; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.TreeSet; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.knowledge.TopDownIndex; +import software.amazon.smithy.model.shapes.MemberShape; +import software.amazon.smithy.model.shapes.OperationShape; +import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.model.shapes.Shape; +import software.amazon.smithy.model.shapes.ShapeId; +import software.amazon.smithy.utils.SmithyInternalApi; + +/** + * Creates schema groupings. + * E.g. used to create disjoint sets of schemas to assist with tree-shaking. + */ +@SmithyInternalApi +public class ShapeTreeOrganizer { + public static final String FILENAME_PREFIX = "schemas"; + + private static final Map INSTANCES = new ConcurrentHashMap<>(); + /** + * Shapes mapped to operations that use them. + */ + private final Map> shapeToOperationDependents = new HashMap<>(); + /** + * Shapes mapped to the largest logical grouping of operations making use of the shape. + */ + private final Map> shapeToOperationalGroup = new HashMap<>(); + /** + * Hashed combined operation names to their numeric group id. + */ + private final Map opGroups = new HashMap<>(); + /** + * Combined operation names mapped to a readable group name. + */ + private final Map groupNames = new HashMap<>(); + private int lastGroup = 0; + private Model model; + + /** + * todo: KnowledgeIndex? + */ + public static ShapeTreeOrganizer forModel(Model model) { + return INSTANCES.computeIfAbsent(model, k -> { + ShapeTreeOrganizer shapeTreeOrganizer = new ShapeTreeOrganizer(); + shapeTreeOrganizer.loadModel(model); + return shapeTreeOrganizer; + }); + } + + /** + * Set the context for this instance. + * todo: KnowledgeIndex? + */ + public void loadModel(Model model) { + if (this.model != null) { + throw new IllegalArgumentException("Model has already been loaded"); + } + this.model = model; + for (ServiceShape service : model.getServiceShapes()) { + for (OperationShape operation : TopDownIndex.of(model).getContainedOperations(service)) { + readOperationClosure(operation, new HashSet<>()); + } + } + + // restack operational groups. + for (Map.Entry> entry : shapeToOperationDependents.entrySet()) { + ShapeId shapeId = entry.getKey(); + TreeSet dependentOperations = entry.getValue(); + shapeToOperationalGroup.put(shapeId, + shapeToOperationDependents.values() + .stream() + .filter(group -> group.containsAll(dependentOperations)) + .max(Comparator.comparing(TreeSet::size)) + .get() + ); + } + + // precompute group allocations. + shapeToOperationalGroup.keySet() + .forEach(this::getGroup); + } + + /** + * @return the group name (filename) of the schema group for the given shape. + */ + public String getGroup(ShapeId id) { + if (!shapeToOperationalGroup.containsKey(id)) { + return getBaseGroup(); + } + TreeSet operations = shapeToOperationalGroup.get(id); + return hashOperationSet(operations); + } + + public boolean isBaseGroup(Shape shape) { + return getGroup(shape.getId()).equals(getBaseGroup()); + } + + public boolean different(Shape a, Shape b) { + return !Objects.equals( + getGroup(a.getId()), + getGroup(b.getId()) + ); + } + + /** + * @return a string hash identifying the group that this set of operations is assigned to. + */ + private String hashOperationSet(TreeSet operations) { + if (operations.size() > 5) { + return getBaseGroup(); + } + String key = joinOperationNames(operations); + if (opGroups.containsKey(key) && groupNames.containsKey(key)) { + return FILENAME_PREFIX + + "_" + opGroups.get(key) + + "_" + groupNames.get(key); + } else { + opGroups.put(key, ++lastGroup); + groupNames.put(key, nominateGroupName(operations)); + } + return FILENAME_PREFIX + + "_" + lastGroup + + "_" + groupNames.get(key); + } + + /** + * Simplistically determines a name for the group of operations + * based on the most commonly observed name or structure. + */ + private String nominateGroupName(TreeSet operations) { + if (operations.size() == 1) { + return operations.iterator().next().getName(); + } + + Set names = operations.stream().map(ShapeId::getName).collect(Collectors.toSet()); + int minLength = 3; + + Stream phrases = names.stream() + .flatMap(operationName -> names.stream() + .filter(otherOperationName -> !otherOperationName.equals(operationName)) + .flatMap(other -> { + Set nounPhrases = new HashSet<>(); + + // expensive, but cached. + for (int i = 0; i < operationName.length(); ++i) { + for (int j = i + 1; j <= operationName.length(); ++j) { + String candidate = operationName.substring(i, j); + + if (candidate.length() >= minLength && other.contains(candidate)) { + boolean validNounPhrase = isValidNounPhrase(operationName, i, j); + if (validNounPhrase) { + nounPhrases.add(candidate); + } + } + } + } + + return nounPhrases.stream(); + }) + ); + + return phrases + .collect(Collectors.groupingBy(s -> s, Collectors.counting())) + .entrySet() + .stream() + .max(Map.Entry.comparingByValue()) + .map(Map.Entry::getKey) + .orElse(""); + } + + /** + * The substring from i to j starts with a capital letter and ends + * with the string or at another capital letter or number. + */ + private static boolean isValidNounPhrase(String name, int i, int j) { + String candidate = name.substring(i, j); + + boolean capitalInitialChar = candidate.substring(0, 1).matches("[A-Z]"); + boolean endsWord = name.length() == j + || name.substring(j, j + 1).matches("[A-Z0-9]"); + + return capitalInitialChar && endsWord; + } + + private String getBaseGroup() { + return FILENAME_PREFIX + "_0"; + } + + /** + * Make known that a shape id is used within a certain operation. + */ + private void register(ShapeId operationId, ShapeId shapeId) { + shapeToOperationDependents.computeIfAbsent(shapeId, k -> new TreeSet<>()).add(operationId); + } + + /** + * Explore the set of shapes in the closure of an operation. + */ + private void readOperationClosure(OperationShape op, Set visited) { + registerShapes(op, op, visited); + op.getInput().ifPresent(inputShape -> { + registerShapes(op, model.expectShape(inputShape), visited); + }); + op.getOutput().ifPresent(outputShape -> { + registerShapes(op, model.expectShape(outputShape), visited); + }); + op.getErrors().forEach(error -> { + registerShapes(op, model.expectShape(error), visited); + }); + } + + private void registerShapes(OperationShape op, Shape shape, Set visited) { + if (shape.isMemberShape()) { + registerShapes(op, model.expectShape(shape.asMemberShape().get().getTarget()), visited); + return; + } + if (visited.contains(shape)) { + return; + } + visited.add(shape); + register(op.getId(), shape.getId()); + + Set memberTargetShapes = shape.getAllMembers().values().stream() + .map(MemberShape::getTarget) + .map(model::expectShape) + .collect(Collectors.toSet()); + + for (Shape memberTargetShape : memberTargetShapes) { + registerShapes(op, memberTargetShape, visited); + } + } + + private String joinOperationNames(TreeSet operations) { + return operations.stream().map(ShapeId::getName).collect(Collectors.joining(",")); + } + + void debug() { + shapeToOperationDependents.forEach((shapeId, operations) -> { + System.out.println(shapeId); + System.out.println(" " + getGroup(shapeId)); + System.out.println( + " operations: " + operations.stream() + .map(ShapeId::getName).collect(Collectors.joining(", ")) + ); + System.out.println(); + }); + } +} diff --git a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/util/StringStore.java b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/util/StringStore.java index 37e97e090e5..3d3625d7153 100644 --- a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/util/StringStore.java +++ b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/util/StringStore.java @@ -5,6 +5,7 @@ package software.amazon.smithy.typescript.codegen.util; +import java.nio.file.Path; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; @@ -16,6 +17,7 @@ import java.util.TreeMap; import java.util.function.Function; import java.util.regex.Pattern; +import software.amazon.smithy.typescript.codegen.TypeScriptWriter; import software.amazon.smithy.utils.SmithyInternalApi; /** @@ -25,7 +27,7 @@ * form of compression on long protocol serde files. */ @SmithyInternalApi -public final class StringStore { +public class StringStore { /** * Words are the component strings found within `camelCaseWords` or `header-dashed-words`. */ @@ -170,4 +172,40 @@ private boolean isNeutral(String variable) { } return true; } + + public WithSchemaWriter useSchemaWriter(TypeScriptWriter writer) { + return new WithSchemaWriter(writer, this); + } + + @SmithyInternalApi + public static final class WithSchemaWriter extends StringStore { + private final TypeScriptWriter writer; + private final StringStore store; + + private WithSchemaWriter( + TypeScriptWriter writer, + StringStore store + ) { + this.writer = writer; + this.store = store; + } + + @Override + public String var(String literal) { + String var = store.var(literal); + writer.addRelativeImport( + var, null, Path.of("./schemas_0") + ); + return var; + } + + @Override + public String var(String literal, String preferredPrefix) { + String var = store.var(literal, preferredPrefix); + writer.addRelativeImport( + var, null, Path.of("./schemas_0") + ); + return var; + } + } } From fe055edb281d64c8495d1fb4a9e550a4ec9d95d6 Mon Sep 17 00:00:00 2001 From: George Fu Date: Sat, 30 Aug 2025 12:58:11 -0400 Subject: [PATCH 2/2] feat: schema codegen bucketing to help with tree-shaking --- .../src/commands/EmptyInputOutputCommand.ts | 2 +- .../src/commands/Float16Command.ts | 2 +- .../src/commands/FractionalSecondsCommand.ts | 2 +- .../src/commands/GreetingWithErrorsCommand.ts | 2 +- .../src/commands/NoInputOutputCommand.ts | 2 +- .../commands/OperationWithDefaultsCommand.ts | 2 +- .../commands/OptionalInputOutputCommand.ts | 2 +- .../src/commands/RecursiveShapesCommand.ts | 2 +- .../src/commands/RpcV2CborDenseMapsCommand.ts | 2 +- .../src/commands/RpcV2CborListsCommand.ts | 2 +- .../commands/RpcV2CborSparseMapsCommand.ts | 2 +- .../commands/SimpleScalarPropertiesCommand.ts | 2 +- .../commands/SparseNullsOperationCommand.ts | 2 +- .../src/schemas/schemas_0.ts | 324 +------------ .../src/schemas/schemas_1_Rpc.ts | 451 ++++++++++++++++++ ...utput.ts => schemas_2_EmptyInputOutput.ts} | 0 ...onds.ts => schemas_3_FractionalSeconds.ts} | 3 +- .../schemas/{schemas_3_.ts => schemas_4_.ts} | 3 +- ...utOutput.ts => schemas_5_NoInputOutput.ts} | 3 +- .../typescript/codegen/CommandGenerator.java | 4 +- .../codegen/schema/SchemaGenerator.java | 67 ++- ...Organizer.java => ShapeGroupingIndex.java} | 119 +++-- 22 files changed, 605 insertions(+), 395 deletions(-) create mode 100644 private/smithy-rpcv2-cbor-schema/src/schemas/schemas_1_Rpc.ts rename private/smithy-rpcv2-cbor-schema/src/schemas/{schemas_1_EmptyInputOutput.ts => schemas_2_EmptyInputOutput.ts} (100%) rename private/smithy-rpcv2-cbor-schema/src/schemas/{schemas_2_FractionalSeconds.ts => schemas_3_FractionalSeconds.ts} (76%) rename private/smithy-rpcv2-cbor-schema/src/schemas/{schemas_3_.ts => schemas_4_.ts} (74%) rename private/smithy-rpcv2-cbor-schema/src/schemas/{schemas_4_NoInputOutput.ts => schemas_5_NoInputOutput.ts} (69%) rename smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/schema/{ShapeTreeOrganizer.java => ShapeGroupingIndex.java} (84%) diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/EmptyInputOutputCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/EmptyInputOutputCommand.ts index 8117e457c5a..bebe9fc7968 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/EmptyInputOutputCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/EmptyInputOutputCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { EmptyStructure } from "../models/models_0"; -import { EmptyInputOutput } from "../schemas/schemas_1_EmptyInputOutput"; +import { EmptyInputOutput } from "../schemas/schemas_2_EmptyInputOutput"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/Float16Command.ts b/private/smithy-rpcv2-cbor-schema/src/commands/Float16Command.ts index 3071dc7b428..e48b71f0800 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/Float16Command.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/Float16Command.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { Float16Output } from "../models/models_0"; -import { Float16 } from "../schemas/schemas_3_"; +import { Float16 } from "../schemas/schemas_4_"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/FractionalSecondsCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/FractionalSecondsCommand.ts index 983f166c7cb..8a9776cd18e 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/FractionalSecondsCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/FractionalSecondsCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { FractionalSecondsOutput } from "../models/models_0"; -import { FractionalSeconds } from "../schemas/schemas_2_FractionalSeconds"; +import { FractionalSeconds } from "../schemas/schemas_3_FractionalSeconds"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/GreetingWithErrorsCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/GreetingWithErrorsCommand.ts index 6f10b204ea9..26ec75a22c3 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/GreetingWithErrorsCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/GreetingWithErrorsCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { GreetingWithErrorsOutput } from "../models/models_0"; -import { GreetingWithErrors } from "../schemas/schemas_0"; +import { GreetingWithErrors } from "../schemas/schemas_1_Rpc"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/NoInputOutputCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/NoInputOutputCommand.ts index a37b89742b0..d93f14eea19 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/NoInputOutputCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/NoInputOutputCommand.ts @@ -1,7 +1,7 @@ // smithy-typescript generated code import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; -import { NoInputOutput } from "../schemas/schemas_4_NoInputOutput"; +import { NoInputOutput } from "../schemas/schemas_5_NoInputOutput"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/OperationWithDefaultsCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/OperationWithDefaultsCommand.ts index 9f4774bb5f1..cfdfaedf5d7 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/OperationWithDefaultsCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/OperationWithDefaultsCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { OperationWithDefaultsInput, OperationWithDefaultsOutput } from "../models/models_0"; -import { OperationWithDefaults } from "../schemas/schemas_0"; +import { OperationWithDefaults } from "../schemas/schemas_1_Rpc"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/OptionalInputOutputCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/OptionalInputOutputCommand.ts index d25861d66f6..cb3a234ecb9 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/OptionalInputOutputCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/OptionalInputOutputCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { SimpleStructure } from "../models/models_0"; -import { OptionalInputOutput } from "../schemas/schemas_0"; +import { OptionalInputOutput } from "../schemas/schemas_1_Rpc"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/RecursiveShapesCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/RecursiveShapesCommand.ts index 764698db544..8ac48b4c99f 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/RecursiveShapesCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/RecursiveShapesCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { RecursiveShapesInputOutput } from "../models/models_0"; -import { RecursiveShapes } from "../schemas/schemas_0"; +import { RecursiveShapes } from "../schemas/schemas_1_Rpc"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborDenseMapsCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborDenseMapsCommand.ts index 1ecb7c572c8..38f98a94ddd 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborDenseMapsCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborDenseMapsCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { RpcV2CborDenseMapsInputOutput } from "../models/models_0"; -import { RpcV2CborDenseMaps } from "../schemas/schemas_0"; +import { RpcV2CborDenseMaps } from "../schemas/schemas_1_Rpc"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborListsCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborListsCommand.ts index b86a40455f1..1111b00fa56 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborListsCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborListsCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { RpcV2CborListInputOutput } from "../models/models_0"; -import { RpcV2CborLists } from "../schemas/schemas_0"; +import { RpcV2CborLists } from "../schemas/schemas_1_Rpc"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborSparseMapsCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborSparseMapsCommand.ts index 1705ee4fca7..5434e479a25 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborSparseMapsCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/RpcV2CborSparseMapsCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { RpcV2CborSparseMapsInputOutput } from "../models/models_0"; -import { RpcV2CborSparseMaps } from "../schemas/schemas_0"; +import { RpcV2CborSparseMaps } from "../schemas/schemas_1_Rpc"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/SimpleScalarPropertiesCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/SimpleScalarPropertiesCommand.ts index 229c21f0bdd..5945cc84fb3 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/SimpleScalarPropertiesCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/SimpleScalarPropertiesCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { SimpleScalarStructure } from "../models/models_0"; -import { SimpleScalarProperties } from "../schemas/schemas_0"; +import { SimpleScalarProperties } from "../schemas/schemas_1_Rpc"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/commands/SparseNullsOperationCommand.ts b/private/smithy-rpcv2-cbor-schema/src/commands/SparseNullsOperationCommand.ts index fc6dbbafbdb..d7bc1c72188 100644 --- a/private/smithy-rpcv2-cbor-schema/src/commands/SparseNullsOperationCommand.ts +++ b/private/smithy-rpcv2-cbor-schema/src/commands/SparseNullsOperationCommand.ts @@ -2,7 +2,7 @@ import { RpcV2ProtocolClientResolvedConfig, ServiceInputTypes, ServiceOutputTypes } from "../RpcV2ProtocolClient"; import { commonParams } from "../endpoint/EndpointParameters"; import { SparseNullsOperationInputOutput } from "../models/models_0"; -import { SparseNullsOperation } from "../schemas/schemas_0"; +import { SparseNullsOperation } from "../schemas/schemas_1_Rpc"; import { getEndpointPlugin } from "@smithy/middleware-endpoint"; import { Command as $Command } from "@smithy/smithy-client"; import { MetadataBearer as __MetadataBearer } from "@smithy/types"; diff --git a/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_0.ts b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_0.ts index 89da2306ee0..0250a19e8fe 100644 --- a/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_0.ts +++ b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_0.ts @@ -131,185 +131,10 @@ export const n2 = "smithy.protocoltests.shared"; // smithy-typescript generated code import { RpcV2ProtocolServiceException as __RpcV2ProtocolServiceException } from "../models/RpcV2ProtocolServiceException"; -import { - ComplexError as __ComplexError, - InvalidGreeting as __InvalidGreeting, - ValidationException as __ValidationException, -} from "../models/index"; -import { error, list, map, op, struct } from "@smithy/core/schema"; +import { error } from "@smithy/core/schema"; /* eslint no-var: 0 */ -export var Unit = "unit" as const; - -export var ValidationException = error( - n0, - _VE, - { - [_e]: _c, - }, - [_m, _fL], - [0, () => ValidationExceptionFieldList], - - __ValidationException -); -export var ValidationExceptionField = struct(n0, _VEF, 0, [_p, _m], [0, 0]); -export var ClientOptionalDefaults = struct(n1, _COD, 0, [_me], [1]); -export var ComplexError = error( - n1, - _CE, - { - [_e]: _c, - }, - [_TL, _N], - [0, () => ComplexNestedErrorData], - - __ComplexError -); -export var ComplexNestedErrorData = struct(n1, _CNED, 0, [_F], [0]); -export var Defaults = struct( - n1, - _D, - 0, - [ - _dS, - _dB, - _dL, - _dT, - _dBe, - _dBef, - _dSe, - _dI, - _dLe, - _dF, - _dD, - _dM, - _dE, - _dIE, - _eS, - _fB, - _eB, - _zB, - _zS, - _zI, - _zL, - _zF, - _zD, - ], - [0, 2, 64 | 0, 4, 21, 1, 1, 1, 1, 1, 1, 128 | 0, 0, 1, 0, 2, 21, 1, 1, 1, 1, 1, 1] -); -export var GreetingWithErrorsOutput = struct(n1, _GWEO, 0, [_g], [0]); -export var InvalidGreeting = error( - n1, - _IG, - { - [_e]: _c, - }, - [_M], - [0], - - __InvalidGreeting -); -export var OperationWithDefaultsInput = struct( - n1, - _OWDI, - 0, - [_de, _cOD, _tLD, _oTLD], - [() => Defaults, () => ClientOptionalDefaults, 0, 1] -); -export var OperationWithDefaultsOutput = struct( - n1, - _OWDO, - 0, - [ - _dS, - _dB, - _dL, - _dT, - _dBe, - _dBef, - _dSe, - _dI, - _dLe, - _dF, - _dD, - _dM, - _dE, - _dIE, - _eS, - _fB, - _eB, - _zB, - _zS, - _zI, - _zL, - _zF, - _zD, - ], - [0, 2, 64 | 0, 4, 21, 1, 1, 1, 1, 1, 1, 128 | 0, 0, 1, 0, 2, 21, 1, 1, 1, 1, 1, 1] -); -export var RecursiveShapesInputOutput = struct(n1, _RSIO, 0, [_n], [() => RecursiveShapesInputOutputNested1]); -export var RecursiveShapesInputOutputNested1 = struct( - n1, - _RSION, - 0, - [_f, _n], - [0, () => RecursiveShapesInputOutputNested2] -); -export var RecursiveShapesInputOutputNested2 = struct( - n1, - _RSIONe, - 0, - [_b, _rM], - [0, () => RecursiveShapesInputOutputNested1] -); -export var RpcV2CborDenseMapsInputOutput = struct( - n1, - _RVCDMIO, - 0, - [_dSM, _dNM, _dBM, _dSMe, _dSMen], - [() => DenseStructMap, 128 | 1, 128 | 2, 128 | 0, map(n1, _DSM, 0, 0, 64 | 0)] -); -export var RpcV2CborListInputOutput = struct( - n1, - _RVCLIO, - 0, - [_sL, _sS, _iL, _bL, _tL, _eL, _iEL, _nSL, _sLt, _bLl], - [64 | 0, 64 | 0, 64 | 1, 64 | 2, 64 | 4, 64 | 0, 64 | 1, list(n2, _NSL, 0, 64 | 0), () => StructureList, 64 | 21] -); -export var RpcV2CborSparseMapsInputOutput = struct( - n1, - _RVCSMIO, - 0, - [_sSM, _sNM, _sBM, _sSMp, _sSMpa], - [ - [() => SparseStructMap, 0], - [() => SparseNumberMap, 0], - [() => SparseBooleanMap, 0], - [() => SparseStringMap, 0], - [() => SparseSetMap, 0], - ] -); -export var SimpleScalarStructure = struct( - n1, - _SSS, - 0, - [_tBV, _fBV, _bV, _dV, _fV, _iV, _lV, _sV, _sVt, _bVl], - [2, 2, 1, 1, 1, 1, 1, 1, 0, 21] -); -export var SimpleStructure = struct(n1, _SS, 0, [_v], [0]); -export var SparseNullsOperationInputOutput = struct( - n1, - _SNOIO, - 0, - [_sSL, _sSMp], - [ - [() => SparseStringList, 0], - [() => SparseStringMap, 0], - ] -); -export var StructureListMember = struct(n1, _SLM, 0, [_a, _b_], [0, 0]); -export var GreetingStruct = struct(n2, _GS, 0, [_h], [0]); export var RpcV2ProtocolServiceException = error( "smithy.ts.sdk.synthetic.smithy.protocoltests.rpcv2Cbor", "RpcV2ProtocolServiceException", @@ -318,150 +143,3 @@ export var RpcV2ProtocolServiceException = error( [], __RpcV2ProtocolServiceException ); -export var ValidationExceptionFieldList = list(n0, _VEFL, 0, () => ValidationExceptionField); -export var StructureList = list(n1, _SL, 0, () => StructureListMember); -export var TestStringList = 64 | 0; - -export var BlobList = 64 | 21; - -export var BooleanList = 64 | 2; - -export var FooEnumList = 64 | 0; - -export var IntegerEnumList = 64 | 1; - -export var IntegerList = 64 | 1; - -export var NestedStringList = list(n2, _NSL, 0, 64 | 0); -export var SparseStringList = list( - n2, - _SSL, - { - [_s]: 1, - }, - 0 -); -export var StringList = 64 | 0; - -export var StringSet = 64 | 0; - -export var TimestampList = 64 | 4; - -export var DenseBooleanMap = 128 | 2; - -export var DenseNumberMap = 128 | 1; - -export var DenseSetMap = map(n1, _DSM, 0, 0, 64 | 0); -export var DenseStringMap = 128 | 0; - -export var DenseStructMap = map(n1, _DSMe, 0, 0, () => GreetingStruct); -export var SparseBooleanMap = map( - n1, - _SBM, - { - [_s]: 1, - }, - 0, - 2 -); -export var SparseNumberMap = map( - n1, - _SNM, - { - [_s]: 1, - }, - 0, - 1 -); -export var SparseSetMap = map( - n1, - _SSM, - { - [_s]: 1, - }, - 0, - 64 | 0 -); -export var SparseStructMap = map( - n1, - _SSMp, - { - [_s]: 1, - }, - 0, - () => GreetingStruct -); -export var TestStringMap = 128 | 0; - -export var SparseStringMap = map( - n2, - _SSMpa, - { - [_s]: 1, - }, - 0, - 0 -); -export var GreetingWithErrors = op( - n1, - _GWE, - 2, - () => Unit, - () => GreetingWithErrorsOutput -); -export var OperationWithDefaults = op( - n1, - _OWD, - 0, - () => OperationWithDefaultsInput, - () => OperationWithDefaultsOutput -); -export var OptionalInputOutput = op( - n1, - _OIO, - 0, - () => SimpleStructure, - () => SimpleStructure -); -export var RecursiveShapes = op( - n1, - _RS, - 0, - () => RecursiveShapesInputOutput, - () => RecursiveShapesInputOutput -); -export var RpcV2CborDenseMaps = op( - n1, - _RVCDM, - 0, - () => RpcV2CborDenseMapsInputOutput, - () => RpcV2CborDenseMapsInputOutput -); -export var RpcV2CborLists = op( - n1, - _RVCL, - 2, - () => RpcV2CborListInputOutput, - () => RpcV2CborListInputOutput -); -export var RpcV2CborSparseMaps = op( - n1, - _RVCSM, - 0, - () => RpcV2CborSparseMapsInputOutput, - () => RpcV2CborSparseMapsInputOutput -); -export var SimpleScalarProperties = op( - n1, - _SSP, - 0, - () => SimpleScalarStructure, - () => SimpleScalarStructure -); -export var SparseNullsOperation = op( - n1, - _SNO, - 0, - () => SparseNullsOperationInputOutput, - () => SparseNullsOperationInputOutput -); diff --git a/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_1_Rpc.ts b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_1_Rpc.ts new file mode 100644 index 00000000000..8f3205f17cd --- /dev/null +++ b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_1_Rpc.ts @@ -0,0 +1,451 @@ +// smithy-typescript generated code +import { + ComplexError as __ComplexError, + InvalidGreeting as __InvalidGreeting, + ValidationException as __ValidationException, +} from "../models/index"; +import { + _CE, + _CNED, + _COD, + _D, + _DSM, + _DSMe, + _F, + _GS, + _GWE, + _GWEO, + _IG, + _M, + _N, + _NSL, + _OIO, + _OWD, + _OWDI, + _OWDO, + _RS, + _RSIO, + _RSION, + _RSIONe, + _RVCDM, + _RVCDMIO, + _RVCL, + _RVCLIO, + _RVCSM, + _RVCSMIO, + _SBM, + _SL, + _SLM, + _SNM, + _SNO, + _SNOIO, + _SS, + _SSL, + _SSM, + _SSMp, + _SSMpa, + _SSP, + _SSS, + _TL, + _VE, + _VEF, + _VEFL, + _a, + _b, + _bL, + _bLl, + _bV, + _bVl, + _b_, + _c, + _cOD, + _dB, + _dBM, + _dBe, + _dBef, + _dD, + _dE, + _dF, + _dI, + _dIE, + _dL, + _dLe, + _dM, + _dNM, + _dS, + _dSM, + _dSMe, + _dSMen, + _dSe, + _dT, + _dV, + _de, + _e, + _eB, + _eL, + _eS, + _f, + _fB, + _fBV, + _fL, + _fV, + _g, + _h, + _iEL, + _iL, + _iV, + _lV, + _m, + _me, + _n, + _nSL, + _oTLD, + _p, + _rM, + _s, + _sBM, + _sL, + _sLt, + _sNM, + _sS, + _sSL, + _sSM, + _sSMp, + _sSMpa, + _sV, + _sVt, + _tBV, + _tL, + _tLD, + _v, + _zB, + _zD, + _zF, + _zI, + _zL, + _zS, + n0, + n1, + n2, +} from "./schemas_0"; +import { error, list, map, op, struct } from "@smithy/core/schema"; + +/* eslint no-var: 0 */ + +export var Unit = "unit" as const; + +export var ValidationException = error( + n0, + _VE, + { + [_e]: _c, + }, + [_m, _fL], + [0, () => ValidationExceptionFieldList], + + __ValidationException +); +export var ValidationExceptionField = struct(n0, _VEF, 0, [_p, _m], [0, 0]); +export var ClientOptionalDefaults = struct(n1, _COD, 0, [_me], [1]); +export var ComplexError = error( + n1, + _CE, + { + [_e]: _c, + }, + [_TL, _N], + [0, () => ComplexNestedErrorData], + + __ComplexError +); +export var ComplexNestedErrorData = struct(n1, _CNED, 0, [_F], [0]); +export var Defaults = struct( + n1, + _D, + 0, + [ + _dS, + _dB, + _dL, + _dT, + _dBe, + _dBef, + _dSe, + _dI, + _dLe, + _dF, + _dD, + _dM, + _dE, + _dIE, + _eS, + _fB, + _eB, + _zB, + _zS, + _zI, + _zL, + _zF, + _zD, + ], + [0, 2, 64 | 0, 4, 21, 1, 1, 1, 1, 1, 1, 128 | 0, 0, 1, 0, 2, 21, 1, 1, 1, 1, 1, 1] +); +export var GreetingWithErrorsOutput = struct(n1, _GWEO, 0, [_g], [0]); +export var InvalidGreeting = error( + n1, + _IG, + { + [_e]: _c, + }, + [_M], + [0], + + __InvalidGreeting +); +export var OperationWithDefaultsInput = struct( + n1, + _OWDI, + 0, + [_de, _cOD, _tLD, _oTLD], + [() => Defaults, () => ClientOptionalDefaults, 0, 1] +); +export var OperationWithDefaultsOutput = struct( + n1, + _OWDO, + 0, + [ + _dS, + _dB, + _dL, + _dT, + _dBe, + _dBef, + _dSe, + _dI, + _dLe, + _dF, + _dD, + _dM, + _dE, + _dIE, + _eS, + _fB, + _eB, + _zB, + _zS, + _zI, + _zL, + _zF, + _zD, + ], + [0, 2, 64 | 0, 4, 21, 1, 1, 1, 1, 1, 1, 128 | 0, 0, 1, 0, 2, 21, 1, 1, 1, 1, 1, 1] +); +export var RecursiveShapesInputOutput = struct(n1, _RSIO, 0, [_n], [() => RecursiveShapesInputOutputNested1]); +export var RecursiveShapesInputOutputNested1 = struct( + n1, + _RSION, + 0, + [_f, _n], + [0, () => RecursiveShapesInputOutputNested2] +); +export var RecursiveShapesInputOutputNested2 = struct( + n1, + _RSIONe, + 0, + [_b, _rM], + [0, () => RecursiveShapesInputOutputNested1] +); +export var RpcV2CborDenseMapsInputOutput = struct( + n1, + _RVCDMIO, + 0, + [_dSM, _dNM, _dBM, _dSMe, _dSMen], + [() => DenseStructMap, 128 | 1, 128 | 2, 128 | 0, map(n1, _DSM, 0, 0, 64 | 0)] +); +export var RpcV2CborListInputOutput = struct( + n1, + _RVCLIO, + 0, + [_sL, _sS, _iL, _bL, _tL, _eL, _iEL, _nSL, _sLt, _bLl], + [64 | 0, 64 | 0, 64 | 1, 64 | 2, 64 | 4, 64 | 0, 64 | 1, list(n2, _NSL, 0, 64 | 0), () => StructureList, 64 | 21] +); +export var RpcV2CborSparseMapsInputOutput = struct( + n1, + _RVCSMIO, + 0, + [_sSM, _sNM, _sBM, _sSMp, _sSMpa], + [ + [() => SparseStructMap, 0], + [() => SparseNumberMap, 0], + [() => SparseBooleanMap, 0], + [() => SparseStringMap, 0], + [() => SparseSetMap, 0], + ] +); +export var SimpleScalarStructure = struct( + n1, + _SSS, + 0, + [_tBV, _fBV, _bV, _dV, _fV, _iV, _lV, _sV, _sVt, _bVl], + [2, 2, 1, 1, 1, 1, 1, 1, 0, 21] +); +export var SimpleStructure = struct(n1, _SS, 0, [_v], [0]); +export var SparseNullsOperationInputOutput = struct( + n1, + _SNOIO, + 0, + [_sSL, _sSMp], + [ + [() => SparseStringList, 0], + [() => SparseStringMap, 0], + ] +); +export var StructureListMember = struct(n1, _SLM, 0, [_a, _b_], [0, 0]); +export var GreetingStruct = struct(n2, _GS, 0, [_h], [0]); +export var ValidationExceptionFieldList = list(n0, _VEFL, 0, () => ValidationExceptionField); +export var StructureList = list(n1, _SL, 0, () => StructureListMember); +export var TestStringList = 64 | 0; + +export var BlobList = 64 | 21; + +export var BooleanList = 64 | 2; + +export var FooEnumList = 64 | 0; + +export var IntegerEnumList = 64 | 1; + +export var IntegerList = 64 | 1; + +export var NestedStringList = list(n2, _NSL, 0, 64 | 0); +export var SparseStringList = list( + n2, + _SSL, + { + [_s]: 1, + }, + 0 +); +export var StringList = 64 | 0; + +export var StringSet = 64 | 0; + +export var TimestampList = 64 | 4; + +export var DenseBooleanMap = 128 | 2; + +export var DenseNumberMap = 128 | 1; + +export var DenseSetMap = map(n1, _DSM, 0, 0, 64 | 0); +export var DenseStringMap = 128 | 0; + +export var DenseStructMap = map(n1, _DSMe, 0, 0, () => GreetingStruct); +export var SparseBooleanMap = map( + n1, + _SBM, + { + [_s]: 1, + }, + 0, + 2 +); +export var SparseNumberMap = map( + n1, + _SNM, + { + [_s]: 1, + }, + 0, + 1 +); +export var SparseSetMap = map( + n1, + _SSM, + { + [_s]: 1, + }, + 0, + 64 | 0 +); +export var SparseStructMap = map( + n1, + _SSMp, + { + [_s]: 1, + }, + 0, + () => GreetingStruct +); +export var TestStringMap = 128 | 0; + +export var SparseStringMap = map( + n2, + _SSMpa, + { + [_s]: 1, + }, + 0, + 0 +); +export var GreetingWithErrors = op( + n1, + _GWE, + 2, + () => Unit, + () => GreetingWithErrorsOutput +); +export var OperationWithDefaults = op( + n1, + _OWD, + 0, + () => OperationWithDefaultsInput, + () => OperationWithDefaultsOutput +); +export var OptionalInputOutput = op( + n1, + _OIO, + 0, + () => SimpleStructure, + () => SimpleStructure +); +export var RecursiveShapes = op( + n1, + _RS, + 0, + () => RecursiveShapesInputOutput, + () => RecursiveShapesInputOutput +); +export var RpcV2CborDenseMaps = op( + n1, + _RVCDM, + 0, + () => RpcV2CborDenseMapsInputOutput, + () => RpcV2CborDenseMapsInputOutput +); +export var RpcV2CborLists = op( + n1, + _RVCL, + 2, + () => RpcV2CborListInputOutput, + () => RpcV2CborListInputOutput +); +export var RpcV2CborSparseMaps = op( + n1, + _RVCSM, + 0, + () => RpcV2CborSparseMapsInputOutput, + () => RpcV2CborSparseMapsInputOutput +); +export var SimpleScalarProperties = op( + n1, + _SSP, + 0, + () => SimpleScalarStructure, + () => SimpleScalarStructure +); +export var SparseNullsOperation = op( + n1, + _SNO, + 0, + () => SparseNullsOperationInputOutput, + () => SparseNullsOperationInputOutput +); diff --git a/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_1_EmptyInputOutput.ts b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_2_EmptyInputOutput.ts similarity index 100% rename from private/smithy-rpcv2-cbor-schema/src/schemas/schemas_1_EmptyInputOutput.ts rename to private/smithy-rpcv2-cbor-schema/src/schemas/schemas_2_EmptyInputOutput.ts diff --git a/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_2_FractionalSeconds.ts b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_3_FractionalSeconds.ts similarity index 76% rename from private/smithy-rpcv2-cbor-schema/src/schemas/schemas_2_FractionalSeconds.ts rename to private/smithy-rpcv2-cbor-schema/src/schemas/schemas_3_FractionalSeconds.ts index bd7028329b2..7f9a11ccc86 100644 --- a/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_2_FractionalSeconds.ts +++ b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_3_FractionalSeconds.ts @@ -1,5 +1,6 @@ // smithy-typescript generated code -import { Unit, _FS, _FSO, _d, n1 } from "./schemas_0"; +import { _FS, _FSO, _d, n1 } from "./schemas_0"; +import { Unit } from "./schemas_1_Rpc"; import { op, struct } from "@smithy/core/schema"; /* eslint no-var: 0 */ diff --git a/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_3_.ts b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_4_.ts similarity index 74% rename from private/smithy-rpcv2-cbor-schema/src/schemas/schemas_3_.ts rename to private/smithy-rpcv2-cbor-schema/src/schemas/schemas_4_.ts index 50292ac5bbe..e44a5e80c78 100644 --- a/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_3_.ts +++ b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_4_.ts @@ -1,5 +1,6 @@ // smithy-typescript generated code -import { Unit, _FO, _Fl, _v, n1 } from "./schemas_0"; +import { _FO, _Fl, _v, n1 } from "./schemas_0"; +import { Unit } from "./schemas_1_Rpc"; import { op, struct } from "@smithy/core/schema"; /* eslint no-var: 0 */ diff --git a/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_4_NoInputOutput.ts b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_5_NoInputOutput.ts similarity index 69% rename from private/smithy-rpcv2-cbor-schema/src/schemas/schemas_4_NoInputOutput.ts rename to private/smithy-rpcv2-cbor-schema/src/schemas/schemas_5_NoInputOutput.ts index e6488cbaf49..d31aec32b48 100644 --- a/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_4_NoInputOutput.ts +++ b/private/smithy-rpcv2-cbor-schema/src/schemas/schemas_5_NoInputOutput.ts @@ -1,5 +1,6 @@ // smithy-typescript generated code -import { Unit, _NIO, n1 } from "./schemas_0"; +import { _NIO, n1 } from "./schemas_0"; +import { Unit } from "./schemas_1_Rpc"; import { op } from "@smithy/core/schema"; /* eslint no-var: 0 */ diff --git a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/CommandGenerator.java b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/CommandGenerator.java index e596013d345..503ea1b45c8 100644 --- a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/CommandGenerator.java +++ b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/CommandGenerator.java @@ -61,7 +61,7 @@ import software.amazon.smithy.typescript.codegen.integration.ProtocolGenerator; import software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin; import software.amazon.smithy.typescript.codegen.schema.SchemaGenerationAllowlist; -import software.amazon.smithy.typescript.codegen.schema.ShapeTreeOrganizer; +import software.amazon.smithy.typescript.codegen.schema.ShapeGroupingIndex; import software.amazon.smithy.typescript.codegen.sections.CommandBodyExtraCodeSection; import software.amazon.smithy.typescript.codegen.sections.CommandConstructorCodeSection; import software.amazon.smithy.typescript.codegen.sections.CommandPropertiesCodeSection; @@ -669,7 +669,7 @@ private void addCommandSpecificPlugins() { } private void writeSchemaSerde() { - ShapeTreeOrganizer shapeTree = ShapeTreeOrganizer.forModel(model); + ShapeGroupingIndex shapeTree = ShapeGroupingIndex.of(model); String operationSchema = reservedWords.escape(operation.getId().getName()); writer.addRelativeImport(operationSchema, null, Paths.get( ".", CodegenUtils.SOURCE_FOLDER, SCHEMAS_FOLDER, shapeTree.getGroup(operation.getId()) diff --git a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/schema/SchemaGenerator.java b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/schema/SchemaGenerator.java index db792ec6ba8..9d8b414d7dc 100644 --- a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/schema/SchemaGenerator.java +++ b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/schema/SchemaGenerator.java @@ -49,13 +49,20 @@ public class SchemaGenerator implements Runnable { public static final String SCHEMAS_FOLDER = "schemas"; private final SchemaReferenceIndex elision; + private final ShapeGroupingIndex treeOrganizer; private final TypeScriptSettings settings; private final SymbolProvider symbolProvider; private final Model model; private final FileManifest fileManifest; private final StringStore store = new StringStore(); + /** + * Keyed by the schema group determined by the ShapeGroupingIndex. + */ private final Map writers = new HashMap<>(); + /** + * Avoids infinite recursion when navigating shape graph. + */ private final Set loadShapesVisited = new HashSet<>(); private final Set structureShapes = new TreeSet<>(); @@ -65,9 +72,11 @@ public class SchemaGenerator implements Runnable { private final Set operationShapes = new TreeSet<>(); private final Set simpleShapes = new TreeSet<>(); + /** + * Used to deconflict schema variable names. + */ private final Set existsAsSchema = new HashSet<>(); private final Set requiresNamingDeconfliction = new HashSet<>(); - private ShapeTreeOrganizer treeOrganizer; private final ReservedWords reservedWords = new ReservedWordsBuilder() .loadWords(Objects.requireNonNull(TypeScriptClientCodegenPlugin.class.getResource("reserved-words.txt"))) @@ -81,6 +90,7 @@ public SchemaGenerator(Model model, elision = SchemaReferenceIndex.of(model); this.settings = settings; this.symbolProvider = symbolProvider; + treeOrganizer = ShapeGroupingIndex.of(model); } /** @@ -88,7 +98,6 @@ public SchemaGenerator(Model model, */ @Override public void run() { - treeOrganizer = ShapeTreeOrganizer.forModel(model); for (ServiceShape service : model.getServiceShapes()) { if (!SchemaGenerationAllowlist.allows(service.getId(), settings)) { return; @@ -139,10 +148,11 @@ public void run() { } } } - - treeOrganizer.debug(); } + /** + * @return writer corresponding to the file that will hold the shape's schema. + */ private TypeScriptWriter getWriter(ShapeId shape) { return writers.computeIfAbsent(treeOrganizer.getGroup(shape), k -> { TypeScriptWriter typeScriptWriter = new TypeScriptWriter(""); @@ -153,6 +163,19 @@ private TypeScriptWriter getWriter(ShapeId shape) { }); } + /** + * @return writer corresponding to the base schemas file (schemas_0.ts). + */ + private TypeScriptWriter getBaseWriter() { + return writers.computeIfAbsent("schemas_0", k -> { + TypeScriptWriter typeScriptWriter = new TypeScriptWriter(""); + typeScriptWriter.write(""" + /* eslint no-var: 0 */ + """); + return typeScriptWriter; + }); + } + /** * Identifies repeated strings among the schemas to use in StringStore. */ @@ -213,6 +236,11 @@ private void loadShapes(Shape shape) { } } + /** + * Since we use the short names for schema objects, in rare cases there may be a + * naming conflict due to shapes with the same short name in different namespaces. + * These shapes will have their variable names deconflicted with a suffix. + */ private void deconflictSchemaVarNames() { Set observedShapeNames = new HashSet<>(); for (Shape shape : existsAsSchema) { @@ -236,6 +264,10 @@ private String getShapeVariableName(Shape shape) { return symbolName; } + /** + * Writes the schema declaration for a simple shape. + * If it has no runtime traits, e.g. a plain string, nothing will be written. + */ private void writeSimpleSchema(Shape shape) { TypeScriptWriter writer = getWriter(shape.getId()); if (elision.traits.hasSchemaTraits(shape)) { @@ -288,8 +320,11 @@ private void writeStructureSchema(StructureShape shape) { }); } + /** + * Writes the synthetic base exception schema. + */ private void writeBaseError() { - TypeScriptWriter writer = writers.get("schemas_0"); + TypeScriptWriter writer = getBaseWriter(); String serviceName = CodegenUtils.getServiceName(settings, model, symbolProvider); String serviceExceptionName = CodegenUtils.getServiceExceptionName(serviceName); @@ -474,6 +509,10 @@ private void writeTraits(Shape shape) { writeTraitsInContext(shape, shape); } + /** + * When the context is not the base group, then any StringStore variables + * are imported from the base group. + */ private void writeTraitsInContext(Shape context, Shape shape) { TypeScriptWriter writer = getWriter(context.getId()); boolean useImportedStrings = !treeOrganizer.isBaseGroup(context); @@ -541,6 +580,10 @@ private String resolveSchema(Shape context, Shape shape) { return (isReference || hasTraits ? "() => " : "") + getShapeVariableName(shape); } + /** + * @return a sentinel value representing a preconfigured schema type. + * @throws IllegalArgumentException when no sentinel value exists, e.g. a non-simple schema was passed in. + */ private String resolveSimpleSchema(Shape shape) { MemberShape memberShape = null; if (shape instanceof MemberShape ms) { @@ -598,6 +641,14 @@ private String resolveSimpleSchema(Shape shape) { throw new IllegalArgumentException("shape is not simple"); } + /** + * For example, the number 5 represents a timestamp (Date-Time) schema with no other traits. + * For lists, the bit modifier 64 is applied, giving 64 | 5 for a list of timestamps. + * For further nested containers, bit masks can no longer be used, necessitating the `sim` simple schema + * wrapper: `sim("namespace", "ListOfLists", 64 | 5, {});`. + * + * @return the container bit modifier attached to the schema numeric value. + */ private String resolveSimpleSchemaNestedContainer(Shape shape, TypeScriptWriter writer) { Shape contained; String factory; @@ -645,6 +696,9 @@ private String resolveSimpleSchemaNestedContainer(Shape shape, TypeScriptWriter } } + /** + * Imports the shape's schema from another file if the context group differs from the shape group. + */ private void checkImportSchema(Shape context, Shape shape) { String shapeGroup = treeOrganizer.getGroup(shape.getId()); if (treeOrganizer.different(context, shape)) { @@ -658,6 +712,9 @@ private String checkImportString(Shape context, String fullString) { return checkImportString(context, fullString, null); } + /** + * Imports a string variable from the base group if the context is not the base group. + */ private String checkImportString(Shape context, String fullString, String prefix) { String var = prefix != null ? store.var(fullString, prefix) : store.var(fullString); if (!treeOrganizer.isBaseGroup(context)) { diff --git a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/schema/ShapeTreeOrganizer.java b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/schema/ShapeGroupingIndex.java similarity index 84% rename from smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/schema/ShapeTreeOrganizer.java rename to smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/schema/ShapeGroupingIndex.java index 9e30d102866..ba43550fcd0 100644 --- a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/schema/ShapeTreeOrganizer.java +++ b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/schema/ShapeGroupingIndex.java @@ -16,6 +16,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.knowledge.KnowledgeIndex; import software.amazon.smithy.model.knowledge.TopDownIndex; import software.amazon.smithy.model.shapes.MemberShape; import software.amazon.smithy.model.shapes.OperationShape; @@ -29,45 +30,89 @@ * E.g. used to create disjoint sets of schemas to assist with tree-shaking. */ @SmithyInternalApi -public class ShapeTreeOrganizer { +public class ShapeGroupingIndex implements KnowledgeIndex { public static final String FILENAME_PREFIX = "schemas"; - private static final Map INSTANCES = new ConcurrentHashMap<>(); + /** + * The maximum number of operations to place into one group (file). + */ + public static final int MAX_OPERATIONS_GROUP_SIZE = 12; + + /** + * Instances of this class for specific models. + */ + private static final Map INSTANCES = new ConcurrentHashMap<>(); + /** * Shapes mapped to operations that use them. */ private final Map> shapeToOperationDependents = new HashMap<>(); + /** * Shapes mapped to the largest logical grouping of operations making use of the shape. */ private final Map> shapeToOperationalGroup = new HashMap<>(); + /** * Hashed combined operation names to their numeric group id. */ private final Map opGroups = new HashMap<>(); + /** * Combined operation names mapped to a readable group name. */ private final Map groupNames = new HashMap<>(); + + /** + * Last group assigned by increasing number. + */ private int lastGroup = 0; - private Model model; /** - * todo: KnowledgeIndex? + * Contextual model. */ - public static ShapeTreeOrganizer forModel(Model model) { + private Model model; + + public static ShapeGroupingIndex of(Model model) { return INSTANCES.computeIfAbsent(model, k -> { - ShapeTreeOrganizer shapeTreeOrganizer = new ShapeTreeOrganizer(); + ShapeGroupingIndex shapeTreeOrganizer = new ShapeGroupingIndex(); shapeTreeOrganizer.loadModel(model); return shapeTreeOrganizer; }); } /** - * Set the context for this instance. - * todo: KnowledgeIndex? + * @return the group name (filename) of the schema group for the given shape. + */ + public String getGroup(ShapeId id) { + if (!shapeToOperationalGroup.containsKey(id)) { + return getBaseGroup(); + } + TreeSet operations = shapeToOperationalGroup.get(id); + return hashOperationSet(operations); + } + + /** + * @return whether shape is in the base group. + */ + public boolean isBaseGroup(Shape shape) { + return getGroup(shape.getId()).equals(getBaseGroup()); + } + + /** + * @return whether two shapes are in different groups. + */ + public boolean different(Shape a, Shape b) { + return !Objects.equals( + getGroup(a.getId()), + getGroup(b.getId()) + ); + } + + /** + * Initialize for given model. */ - public void loadModel(Model model) { + private void loadModel(Model model) { if (this.model != null) { throw new IllegalArgumentException("Model has already been loaded"); } @@ -82,12 +127,14 @@ public void loadModel(Model model) { for (Map.Entry> entry : shapeToOperationDependents.entrySet()) { ShapeId shapeId = entry.getKey(); TreeSet dependentOperations = entry.getValue(); + shapeToOperationalGroup.put(shapeId, shapeToOperationDependents.values() .stream() + .filter(group -> group.size() < MAX_OPERATIONS_GROUP_SIZE) .filter(group -> group.containsAll(dependentOperations)) .max(Comparator.comparing(TreeSet::size)) - .get() + .orElse(dependentOperations) ); } @@ -96,33 +143,11 @@ public void loadModel(Model model) { .forEach(this::getGroup); } - /** - * @return the group name (filename) of the schema group for the given shape. - */ - public String getGroup(ShapeId id) { - if (!shapeToOperationalGroup.containsKey(id)) { - return getBaseGroup(); - } - TreeSet operations = shapeToOperationalGroup.get(id); - return hashOperationSet(operations); - } - - public boolean isBaseGroup(Shape shape) { - return getGroup(shape.getId()).equals(getBaseGroup()); - } - - public boolean different(Shape a, Shape b) { - return !Objects.equals( - getGroup(a.getId()), - getGroup(b.getId()) - ); - } - /** * @return a string hash identifying the group that this set of operations is assigned to. */ private String hashOperationSet(TreeSet operations) { - if (operations.size() > 5) { + if (operations.size() > MAX_OPERATIONS_GROUP_SIZE) { return getBaseGroup(); } String key = joinOperationNames(operations); @@ -140,8 +165,9 @@ private String hashOperationSet(TreeSet operations) { } /** - * Simplistically determines a name for the group of operations + * Determines a name for the group of operations * based on the most commonly observed name or structure. + * Uses "longest common phrase" algorithm. */ private String nominateGroupName(TreeSet operations) { if (operations.size() == 1) { @@ -155,7 +181,7 @@ private String nominateGroupName(TreeSet operations) { .flatMap(operationName -> names.stream() .filter(otherOperationName -> !otherOperationName.equals(operationName)) .flatMap(other -> { - Set nounPhrases = new HashSet<>(); + Set wordPhrases = new HashSet<>(); // expensive, but cached. for (int i = 0; i < operationName.length(); ++i) { @@ -165,13 +191,13 @@ private String nominateGroupName(TreeSet operations) { if (candidate.length() >= minLength && other.contains(candidate)) { boolean validNounPhrase = isValidNounPhrase(operationName, i, j); if (validNounPhrase) { - nounPhrases.add(candidate); + wordPhrases.add(candidate); } } } } - return nounPhrases.stream(); + return wordPhrases.stream(); }) ); @@ -225,6 +251,10 @@ private void readOperationClosure(OperationShape op, Set visited) { }); } + /** + * Registers knowledge of the shape in the context of an operation. + * Recurses on referenced shapes in the input shape. + */ private void registerShapes(OperationShape op, Shape shape, Set visited) { if (shape.isMemberShape()) { registerShapes(op, model.expectShape(shape.asMemberShape().get().getTarget()), visited); @@ -246,19 +276,10 @@ private void registerShapes(OperationShape op, Shape shape, Set visited) } } + /** + * Used to create a hash of a set of operations. + */ private String joinOperationNames(TreeSet operations) { return operations.stream().map(ShapeId::getName).collect(Collectors.joining(",")); } - - void debug() { - shapeToOperationDependents.forEach((shapeId, operations) -> { - System.out.println(shapeId); - System.out.println(" " + getGroup(shapeId)); - System.out.println( - " operations: " + operations.stream() - .map(ShapeId::getName).collect(Collectors.joining(", ")) - ); - System.out.println(); - }); - } }