From 8d609d4a7ced8f9439bccc4596b05c547eb916b0 Mon Sep 17 00:00:00 2001 From: sbaluja Date: Mon, 20 Jul 2026 16:50:08 -0400 Subject: [PATCH 01/19] Smithy model gen plugin extended Smithy model gen plugin extended Route raw streaming-payload requests through stream source includes/usings for C2J parity Delegate InitialResponse header ctor to default ctor for member initialization Define GetBody() for event-stream input requests to fix link error Emit member-driven serde source includes in request/result/initial-response for C2J parity Emit HashingUtils.h in sub-object source for blob members for C2J parity Emit member doc comment on streaming result payload accessor for C2J parity Return Optional and fail fast instead of null in streaming-member helpers Render event-stream input member as shared_ptr with GetBody override for C2J parity Generate outgoing event-stream unions as EventEncoderStream subclasses for C2J parity Gate SerializePayload on streaming payload across all protocols for C2J parity Treat httpPayload blob/string members as streaming for C2J parity Type modeled exceptions concretely in event-stream unions for C2J parity Render InitialResponse members from result shape for C2J parity Map sensitive blobs to CryptoBuffer and document getters to DocumentView for C2J parity Omit private section for memberless sub-object shapes for C2J parity Render non-streaming union shapes as sub-object model files for C2J parity Drop service Errors include from event-stream union header for C2J parity Remove todo comment Initialize idempotency-token members with PseudoRandomUUID for C2J parity Fail fast on unmapped FileKind in serde include/using switches Sub-object headers must not include the serializer (#include parity) Split XML InitialResponse serde set from result set (S3 event-stream #include parity) Remove legacy serde write-hooks; ProtocolTraits owns include/using sets Fix InitialResponse serde set to exclude AWSStringStream (#include parity) Route event-stream handler/InitialResponse includes through IncludeSets Route result/sub-object includes through IncludeSets + serdeIncludes(FileKind) Make each ProtocolTraits declare serdeIncludes/serdeUsings sets directly Route request-source includes through IncludeSets + serdeIncludes(FileKind) Add IncludeSets helper for per-file-kind base includes Add data-driven serdeIncludes/serdeUsings(FileKind) to ProtocolTraits Add FileKind enum for per-file-kind serde include sets Event stream handler serde includes and InitialResponse namespace block Result source includes per protocol fix Fix request level includes per protocol Perfect forwarding for maps/lists codegen fix Query protocol include fixes, enum name fixes, log tag fixes Seperate result include headers and add ResponseMetaData for query Fix stream result member hardcoding to be member shape Drop redundant URI.h include from request headers for C2J parity Pin request/result structural surface across all six protocols Extract ResponseMetadata/requestId in Query/EC2 results Set HTTP-status-code result members from response code Render streaming httpPayload results as move-only ResponseStream classes Classify raw streaming httpPayload results distinct from event streams Emit HasBeenSet accessors for CBOR results via usesRequiredField hook Gate Query/EC2 request methods on bindings; keep protected DumpBodyToUrl Gate REST-XML request methods on header/query bindings Extract CborProtocolTraits with CBOR-specific types and includes Gate JSON/REST_JSON request methods on bindings and split target-header + payload body Generate request class for no-input (Unit) operations to match C2J Emit URI.h include for requests with query-string or query-protocol methods Add trait-driven request-contract defaults and widen ProtocolTraits signatures Add REST_JSON protocol variant distinct from awsJson-RPC Protocol specific request contract (Headers, URL) Fix typos/capatilization issues Remove stale plan references from codegen comments Thread resolved protocol into ShapeClassifier for a single resolution point Migrate EventStreamRenderer to ProtocolTraits Migrate RequestRenderer to ProtocolTraits Migrate ResultRenderer to ProtocolTraits Migrate SubObjectRenderer to ProtocolTraits Add characterization tests pinning generated model output per protocol Null checks -> Optional Fix utf-8 bom Generate event stream model artifacts in Smithy codegen Add response-side event stream generation (handler, initial response, and event stream union) plus request augmentation for simplex streaming operations, closing the gap versus C2J for kinesis SubscribeToShard and bedrock-runtime streaming operations. - Add EventStreamRenderer producing the handler and initial-response (with serde stubs) and the header-only event stream union, matching C2J which emits no .cpp for the union. - Augment RequestRenderer with HasEventStreamResponse/IsEventStreamRequest and the decoder/handler accessors, placing members to match C2J ordering. - Add event stream detection helpers to ShapeClassifier and event-stream serde stub helpers to SerdeStub. - Restore handler and union documentation to match C2J. - Deduplicate renderClassDocComment into MemberRenderer and emit the file copyright header once from CppWriterDelegator. Add event-stream augmentation to RequestRenderer Add EventStream union generation to EventStreamRenderer Add InitialResponse generation to EventStreamRenderer Add EventStreamRenderer with handler generation Add event-stream serde stub helpers to SerdeStub Add event stream detection helpers to ShapeClassifier Use FileManifest API in CppWriterDelegator Enables Smithy's built-in change detection and file tracking instead of raw Files.writeString(). Deduplicate MemberRenderer public section methods Extract shared logic into renderMembers(emitHasBeenSet) to eliminate ~100 lines of near-identical code between request and result rendering. Extract ShapeRenderer interface and per-classification renderers ModelGenerator is now a thin dispatcher that routes classified shapes to registered ShapeRenderer implementations. Adding new classification types (e.g., event streams) requires only a new renderer class, not editing the orchestrator. - EnumShapeRenderer, SubObjectRenderer, RequestRenderer, ResultRenderer - Consolidate isPrimitive() into CppTypeMapper - Promote writeDocComment/collapseWhitespace to public in MemberRenderer - No behavioral change to generated output Fix correctness bugs in model codegen plugin - Fix typos in EnumRenderer FORBIDDEN_WORDS: co_yeild->co_yield, moduel->module - Make generateResultSource/Header protocol-aware (was hardcoded to JSON) - Fix endpoint context param accessor casing (need PascalCase for C++ accessors) --- crt/aws-crt-cpp | 2 +- .../generators/CppImportContainer.java | 4 +- .../generators/model/CppTypeMapper.java | 112 ++++++- .../generators/model/EnumRenderer.java | 4 +- .../generators/model/MemberRenderer.java | 247 ++++++++++++---- .../generators/model/ModelGenerator.java | 5 + .../generators/model/ProtocolResolver.java | 20 +- .../generators/model/SerdeStub.java | 160 ++++++++++ .../generators/model/ShapeClassifier.java | 140 +++++++-- .../model/protocol/CborProtocolTraits.java | 229 +++++++++++++++ .../generators/model/protocol/FileKind.java | 28 ++ .../model/protocol/JsonProtocolTraits.java | 109 ++++++- .../model/protocol/ProtocolTraits.java | 183 +++++++++++- .../protocol/QueryXmlProtocolTraits.java | 140 ++++++++- .../model/protocol/RestXmlProtocolTraits.java | 88 +++++- .../model/renderers/EnumShapeRenderer.java | 3 +- .../model/renderers/EventStreamRenderer.java | 130 +++++++-- .../model/renderers/IncludeSets.java | 93 ++++++ .../OutgoingEventStreamRenderer.java | 197 +++++++++++++ .../model/renderers/RequestRenderer.java | 182 ++++++++++-- .../model/renderers/ResultRenderer.java | 244 ++++++++++++++-- .../model/renderers/SubObjectRenderer.java | 69 +++-- .../model/transforms/GlobalTransforms.java | 80 ++++- .../generators/model/CppTypeMapperTest.java | 124 ++++++++ .../generators/model/EnumRendererTest.java | 35 +++ .../model/EventStreamRendererTest.java | 106 ++++++- .../model/GlobalTransformsTest.java | 72 +++++ .../generators/model/MemberRendererTest.java | 216 ++++++++++++++ .../OutgoingEventStreamRendererTest.java | 144 +++++++++ .../model/ProtocolResolverTest.java | 29 +- .../ProtocolTraitsCharacterizationTest.java | 273 ++++++++++++++++- .../generators/model/RequestRendererTest.java | 177 ++++++++++- .../generators/model/ResultRendererTest.java | 274 ++++++++++++++++++ .../generators/model/SerdeStubTest.java | 49 ++++ .../generators/model/ShapeClassifierTest.java | 121 ++++++++ .../model/SubObjectRendererTest.java | 176 +++++++++++ .../protocol/CborProtocolTraitsTest.java | 191 ++++++++++++ .../model/protocol/FileKindTest.java | 23 ++ .../protocol/JsonProtocolTraitsTest.java | 87 +++++- .../ProtocolTraitsIncludeSetTest.java | 167 +++++++++++ .../protocol/ProtocolTraitsSerdeTest.java | 40 +++ .../ProtocolTraitsStreamingPayloadTest.java | 112 +++++++ .../model/protocol/XmlProtocolTraitsTest.java | 143 ++++++++- .../model/renderers/IncludeSetsTest.java | 82 ++++++ 44 files changed, 4840 insertions(+), 270 deletions(-) create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SerdeStub.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraits.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/FileKind.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSets.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/OutgoingEventStreamRenderer.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/OutgoingEventStreamRendererTest.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ResultRendererTest.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SerdeStubTest.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SubObjectRendererTest.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraitsTest.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/FileKindTest.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsIncludeSetTest.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsStreamingPayloadTest.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSetsTest.java diff --git a/crt/aws-crt-cpp b/crt/aws-crt-cpp index 851d8d003c9d..2343b63d8be7 160000 --- a/crt/aws-crt-cpp +++ b/crt/aws-crt-cpp @@ -1 +1 @@ -Subproject commit 851d8d003c9d5150edab56807e2393013f3771de +Subproject commit 2343b63d8be7cbe209918e032f6204c75cd9a84e diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppImportContainer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppImportContainer.java index 8c26688ae5f0..f9d763a19111 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppImportContainer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppImportContainer.java @@ -11,7 +11,9 @@ /** * CppImportContainer tracks symbols used in code generation. - * For C++, we handle includes manually via writeInclude method. + *

For C++, includes are managed manually (see IncludeSets / ProtocolTraits.serdeIncludes); + * this container is intentionally a no-op sink so Smithy's SymbolWriter contract is satisfied + * without duplicating the manual include logic. */ public class CppImportContainer implements ImportContainer { private final Set imports = new HashSet<>(); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java index a8f29d1ca747..92e5835eb31a 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java @@ -10,6 +10,12 @@ import software.amazon.smithy.model.shapes.MemberShape; import software.amazon.smithy.model.shapes.Shape; import software.amazon.smithy.model.shapes.StructureShape; +import software.amazon.smithy.model.traits.HttpHeaderTrait; +import software.amazon.smithy.model.traits.HttpPrefixHeadersTrait; +import software.amazon.smithy.model.traits.HttpQueryParamsTrait; +import software.amazon.smithy.model.traits.HttpQueryTrait; +import software.amazon.smithy.model.traits.IdempotencyTokenTrait; +import software.amazon.smithy.model.traits.SensitiveTrait; import java.util.ArrayList; import java.util.List; @@ -28,6 +34,24 @@ public final class CppTypeMapper { private CppTypeMapper() { } + /** + * Returns the C++ type/file name for a shape, capitalizing the first character so that + * lowerCamel Smithy shape names (e.g. IAM's {@code statusType}) become UpperCamel C++ + * identifiers ({@code StatusType}). This matches the legacy C2J normalization, which + * upper-camel-cases every shape name at model load + * ({@code C2jModelToGeneratorModelTransformer}). + * + * @param shape the shape whose C++ type/file name is needed + * @return the shape's name with its first character upper-cased + */ + public static String cppShapeName(Shape shape) { + String name = shape.getId().getName(); + if (name.isEmpty()) { + return name; + } + return Character.toUpperCase(name.charAt(0)) + name.substring(1); + } + /** * Returns the C++ type string for the given Smithy shape. * @@ -36,15 +60,32 @@ private CppTypeMapper() { * @return the C++ type name (e.g., {@code "Aws::String"}, {@code "Aws::Vector"}) */ public static String getCppType(Shape shape, Model model) { + return getCppType(shape, model, false); + } + + /** + * Returns the C++ type string for the given Smithy shape. + * + * @param shape the shape to map + * @param model the model (needed to resolve list/map member targets) + * @param wideIntegers when {@code true}, {@code integer} maps to {@code int64_t} instead of + * {@code int}. C2J applies this only under the CBOR protocol + * ({@code CORAL_TYPE_TO_CBOR_CPP_TYPE_MAPPING}: {@code integer -> int64_t}), and only + * in the file kinds whose templates set {@code $protocol == "smithy-rpc-v2-cbor"} — + * the CBOR sub-object and result headers. Request headers use the shared + * {@code RequestHeader.vm}, which does not, so they keep {@code int}. {@code long} is + * {@code long long} in every mapping and is unaffected. + */ + public static String getCppType(Shape shape, Model model, boolean wideIntegers) { // Check enum BEFORE string — EnumShape extends StringShape in Smithy if (shape.isEnumShape()) { - return shape.getId().getName(); + return cppShapeName(shape); } if (shape.isStringShape()) { return "Aws::String"; } if (shape.isIntegerShape()) { - return "int"; + return wideIntegers ? "int64_t" : "int"; } if (shape.isLongShape()) { return "long long"; @@ -56,24 +97,28 @@ public static String getCppType(Shape shape, Model model) { return "double"; } if (shape.isBlobShape()) { - return "Aws::Utils::ByteBuffer"; + // C2J maps a @sensitive blob to CryptoBuffer (the "sensitive_blob" type-mapping key + // in CppViewHelper); a plain blob stays ByteBuffer. Both live in . + return shape.hasTrait(SensitiveTrait.class) + ? "Aws::Utils::CryptoBuffer" : "Aws::Utils::ByteBuffer"; } if (shape.isTimestampShape()) { return "Aws::Utils::DateTime"; } if (shape.isStructureShape() || shape.isUnionShape()) { - return shape.getId().getName(); + return cppShapeName(shape); } if (shape.isListShape()) { ListShape list = shape.asListShape().get(); Shape member = model.expectShape(list.getMember().getTarget()); - return "Aws::Vector<" + getCppType(member, model) + ">"; + return "Aws::Vector<" + getCppType(member, model, wideIntegers) + ">"; } if (shape.isMapShape()) { MapShape map = shape.asMapShape().get(); Shape key = model.expectShape(map.getKey().getTarget()); Shape value = model.expectShape(map.getValue().getTarget()); - return "Aws::Map<" + getCppType(key, model) + ", " + getCppType(value, model) + ">"; + return "Aws::Map<" + getCppType(key, model, wideIntegers) + ", " + + getCppType(value, model, wideIntegers) + ">"; } if (shape.isDocumentShape()) { return "Aws::Utils::Document"; @@ -91,7 +136,7 @@ public static String getCppType(Shape shape, Model model) { */ public static Optional getDefaultValue(Shape shape) { if (shape.isEnumShape()) { - return Optional.of(shape.getId().getName() + "::NOT_SET"); + return Optional.of(cppShapeName(shape) + "::NOT_SET"); } if (shape.isIntegerShape() || shape.isLongShape()) { return Optional.of("0"); @@ -149,7 +194,7 @@ public static boolean needsHasBeenSetFlag(Shape shape) { public static Optional getIncludeForMemberType(Shape shape, Model model, String projectName) { // Check enum BEFORE string — EnumShape extends StringShape in Smithy if (shape.isEnumShape()) { - return Optional.of(""); + return Optional.of(""); } if (shape.isStringShape()) { return Optional.of(""); @@ -167,7 +212,7 @@ public static Optional getIncludeForMemberType(Shape shape, Model model, return Optional.of(""); } if (shape.isStructureShape() || shape.isUnionShape()) { - return Optional.of(""); + return Optional.of(""); } if (shape.isDocumentShape()) { return Optional.of(""); @@ -185,7 +230,7 @@ public static Optional getIncludeForMemberType(Shape shape, Model model, * @param projectName the service project name for model-relative includes * @return sorted list of include lines (e.g., {@code ["", ...]}) */ - public static List getIncludesForShape(StructureShape structureShape, Model model, String projectName) { + public static List getIncludesForShape(Shape structureShape, Model model, String projectName) { Set includes = new TreeSet<>(); for (MemberShape member : structureShape.getAllMembers().values()) { Shape target = model.expectShape(member.getTarget()); @@ -203,7 +248,54 @@ public static List getIncludesForShape(StructureShape structureShape, Mo getIncludeForMemberType(key, model, projectName).ifPresent(includes::add); getIncludeForMemberType(value, model, projectName).ifPresent(includes::add); } + // @idempotencyToken members are brace-initialized with + // Aws::Utils::UUID::PseudoRandomUUID(), which requires UUID.h. Matches C2J + // (CppViewHelper.computeMemberIncludeName). + if (member.hasTrait(IdempotencyTokenTrait.class)) { + includes.add(""); + } + } + return new ArrayList<>(includes); + } + + /** + * Returns the serde-implementation includes a shape's source file needs, as bare + * paths (no angle brackets). Mirrors C2J's {@code CppViewHelper.computeSourceIncludes}: + * a blob member (or list/map of blobs) pulls {@code HashingUtils.h} for Base64 serde, and a + * header/query-bound member pulls {@code AWSStringStream.h}. These are distinct from the + * member-type includes returned by {@link #getIncludesForShape} (which serve the + * header); C2J keeps the two sets separate and lists in the source only what the header does + * not already provide. + */ + public static List getSourceIncludesForShape(Shape structureShape, Model model, String projectName) { + Set includes = new TreeSet<>(); + for (MemberShape member : structureShape.getAllMembers().values()) { + Shape target = model.expectShape(member.getTarget()); + if (referencesBlob(target, model)) { + includes.add("aws/core/utils/HashingUtils.h"); + } else if (member.hasTrait(HttpHeaderTrait.class) + || member.hasTrait(HttpPrefixHeadersTrait.class) + || member.hasTrait(HttpQueryTrait.class) + || member.hasTrait(HttpQueryParamsTrait.class)) { + includes.add("aws/core/utils/memory/stl/AWSStringStream.h"); + } } return new ArrayList<>(includes); } + + /** True if {@code shape} is a blob, a list of blobs, or a map whose key or value is a blob. */ + private static boolean referencesBlob(Shape shape, Model model) { + if (shape.isBlobShape()) { + return true; + } + if (shape.isListShape()) { + return model.expectShape(shape.asListShape().get().getMember().getTarget()).isBlobShape(); + } + if (shape.isMapShape()) { + MapShape map = shape.asMapShape().get(); + return model.expectShape(map.getKey().getTarget()).isBlobShape() + || model.expectShape(map.getValue().getTarget()).isBlobShape(); + } + return false; + } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/EnumRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/EnumRenderer.java index c04466d3a7c5..4901d639a661 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/EnumRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/EnumRenderer.java @@ -42,7 +42,7 @@ private EnumRenderer() { */ public static void renderHeader(CppWriter writer, Shape enumShape, String serviceName, String exportMacro, String projectName) { - String enumName = enumShape.getId().getName(); + String enumName = CppTypeMapper.cppShapeName(enumShape); List values = getEnumValues(enumShape); writer.write("#pragma once"); @@ -98,7 +98,7 @@ public static void renderHeader(CppWriter writer, Shape enumShape, String servic */ public static void renderSource(CppWriter writer, Shape enumShape, String serviceName, String exportMacro, String projectName) { - String enumName = enumShape.getId().getName(); + String enumName = CppTypeMapper.cppShapeName(enumShape); List values = getEnumValues(enumShape); List wireValues = getEnumWireValues(enumShape); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java index e9554b96b1c9..d08fd344f191 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java @@ -13,6 +13,7 @@ import software.amazon.smithy.model.shapes.Shape; import software.amazon.smithy.model.shapes.StructureShape; import software.amazon.smithy.model.traits.DocumentationTrait; +import software.amazon.smithy.model.traits.IdempotencyTokenTrait; import java.util.Map; @@ -48,23 +49,81 @@ private MemberRenderer() { * @param exportMacro the export macro (e.g., "AWS_KINESIS_API") * @param className the C++ class name (e.g., "ChildShard") */ - public static void renderPublicSection(CppWriter writer, StructureShape shape, + public static void renderPublicSection(CppWriter writer, Shape shape, Model model, String exportMacro, String className) { - renderMembers(writer, shape, model, exportMacro, className, true); + renderMembers(writer, shape, model, exportMacro, className, true, null, false); } /** - * Writes public accessor methods for result shapes (no HasBeenSet methods). + * Like {@link #renderPublicSection(CppWriter, Shape, Model, String, String)} but widens + * {@code integer} members to {@code int64_t} when {@code wideIntegers} is set (CBOR sub-objects). + */ + public static void renderPublicSection(CppWriter writer, Shape shape, + Model model, String exportMacro, String className, + boolean wideIntegers) { + renderMembers(writer, shape, model, exportMacro, className, true, null, wideIntegers); + } + + /** + * Writes public accessor methods for result shapes. Result classes never emit + * {@code HasBeenSet()} accessors: every protocol's result header sets + * {@code useRequiredField=false} in C2J (only sub-object / request headers set it true). * * @param writer the CppWriter to write to * @param shape the structure shape whose members to render * @param model the model (for resolving member targets) - * @param exportMacro the export macro (e.g., "AWS_KINESIS_API") - * @param className the C++ class name (e.g., "GetItemResult") + * @param exportMacro the export macro (e.g., "AWS_KINESIS_API") + * @param className the C++ class name (e.g., "GetItemResult") */ public static void renderPublicSectionForResult(CppWriter writer, StructureShape shape, - Model model, String exportMacro, String className) { - renderMembers(writer, shape, model, exportMacro, className, false); + Model model, String exportMacro, String className, + boolean wideIntegers) { + renderMembers(writer, shape, model, exportMacro, className, false, null, wideIntegers); + } + + /** + * Renders result accessors for every member except {@code excludeMemberName}. Used by + * streaming results, whose {@code @httpPayload} member is rendered separately as a + * {@code GetBody()} / {@code ReplaceBody} pair. Like {@link #renderPublicSectionForResult}, + * result members never get {@code HasBeenSet()} accessors. + */ + public static void renderPublicSectionForResultExcluding(CppWriter writer, StructureShape shape, + Model model, String exportMacro, String className, + String excludeMemberName, boolean wideIntegers) { + renderMembers(writer, shape, model, exportMacro, className, false, excludeMemberName, wideIntegers); + } + + /** Writes data member declarations, skipping {@code excludeMemberName}. */ + public static void renderPrivateDataMembersExcluding(CppWriter writer, StructureShape shape, + Model model, String excludeMemberName) { + renderPrivateDataMembersExcluding(writer, shape, model, excludeMemberName, false); + } + + /** Data member declarations excluding one member, widening {@code integer} when requested. */ + public static void renderPrivateDataMembersExcluding(CppWriter writer, StructureShape shape, + Model model, String excludeMemberName, + boolean wideIntegers) { + java.util.List> entries = + new java.util.ArrayList<>(shape.getAllMembers().entrySet()); + entries.removeIf(e -> e.getKey().equals(excludeMemberName)); + for (int i = 0; i < entries.size(); i++) { + Map.Entry entry = entries.get(i); + writeDataMember(writer, entry.getValue(), entry.getKey(), model, wideIntegers); + if (i < entries.size() - 1) { + writer.write(""); + } + } + } + + /** Writes HasBeenSet flags, skipping {@code excludeMemberName}. */ + public static void renderPrivateHasBeenSetFlagsExcluding(CppWriter writer, StructureShape shape, + Model model, String excludeMemberName) { + for (Map.Entry entry : shape.getAllMembers().entrySet()) { + if (entry.getKey().equals(excludeMemberName)) { + continue; + } + writeHasBeenSetFlag(writer, entry.getValue(), entry.getKey()); + } } /** @@ -77,19 +136,38 @@ public static void renderPublicSectionForResult(CppWriter writer, StructureShape * @param className the C++ class name (e.g., "ChildShard") * @param emitHasBeenSet whether to emit HasBeenSet() accessor methods */ - private static void renderMembers(CppWriter writer, StructureShape shape, + private static void renderMembers(CppWriter writer, Shape shape, Model model, String exportMacro, String className, boolean emitHasBeenSet) { + renderMembers(writer, shape, model, exportMacro, className, emitHasBeenSet, null, false); + } + + /** + * Shared member-rendering implementation with an optional excluded member. Streaming + * results emit their {@code @httpPayload} member via a dedicated {@code GetBody()} / + * {@code ReplaceBody} accessor pair, so that member is skipped here. + * + * @param excludeMemberName member name to skip, or {@code null} to render all members + */ + private static void renderMembers(CppWriter writer, Shape shape, + Model model, String exportMacro, String className, + boolean emitHasBeenSet, String excludeMemberName, boolean wideIntegers) { java.util.List> members = new java.util.ArrayList<>(shape.getAllMembers().entrySet()); + members.removeIf(e -> e.getKey().equals(excludeMemberName)); for (int i = 0; i < members.size(); i++) { Map.Entry entry = members.get(i); String memberName = entry.getKey(); MemberShape member = entry.getValue(); Shape targetShape = model.expectShape(member.getTarget()); - String cppType = CppTypeMapper.getCppType(targetShape, model); + String cppType = CppTypeMapper.getCppType(targetShape, model, wideIntegers); String fieldName = "m_" + decapitalize(memberName); - String templateParam = memberName + "T"; + // Method names and template params use the capitalized member name to match the + // legacy C2J convention (e.g. member "extendedKeyUsage" -> GetExtendedKeyUsage, + // ExtendedKeyUsageHasBeenSet, template param ExtendedKeyUsageT). Field names keep + // the decapitalized form (m_extendedKeyUsage). + String methodName = capitalize(memberName); + String templateParam = methodName + "T"; writer.write("///@{"); @@ -99,52 +177,56 @@ private static void renderMembers(CppWriter writer, StructureShape shape, writer.write(""); } - // Getter - if (isPrimitive(targetShape) || targetShape.isEnumShape()) { - writer.write("inline $L Get$L() const { return $L; }", cppType, memberName, fieldName); + // Getter. Documents are special-cased to return Aws::Utils::DocumentView by value + // (the field and setter keep Aws::Utils::Document), matching C2J's + // ModelClassMembersAndInlines.vm $returnType handling. + if (targetShape.isDocumentShape()) { + writer.write("inline Aws::Utils::DocumentView Get$L() const { return $L; }", methodName, fieldName); + } else if (isPrimitive(targetShape) || targetShape.isEnumShape()) { + writer.write("inline $L Get$L() const { return $L; }", cppType, methodName, fieldName); } else { - writer.write("inline const $L& Get$L() const { return $L; }", cppType, memberName, fieldName); + writer.write("inline const $L& Get$L() const { return $L; }", cppType, methodName, fieldName); } // HasBeenSet (only for non-result shapes) if (emitHasBeenSet) { - writer.write("inline bool $LHasBeenSet() const { return $LHasBeenSet; }", memberName, fieldName); + writer.write("inline bool $LHasBeenSet() const { return $LHasBeenSet; }", methodName, fieldName); } if (targetShape.isEnumShape() || isPrimitive(targetShape)) { - writer.openBlock("inline void Set$L($L value) {", "}", memberName, cppType, () -> { + writer.openBlock("inline void Set$L($L value) {", "}", methodName, cppType, () -> { writer.write("$LHasBeenSet = true;", fieldName); writer.write("$L = value;", fieldName); }); - writer.openBlock("inline $L& With$L($L value) {", "}", className, memberName, cppType, () -> { - writer.write("Set$L(value);", memberName); + writer.openBlock("inline $L& With$L($L value) {", "}", className, methodName, cppType, () -> { + writer.write("Set$L(value);", methodName); writer.write("return *this;"); }); } else { writer.write("template ", templateParam, cppType); - writer.openBlock("void Set$L($L&& value) {", "}", memberName, templateParam, () -> { + writer.openBlock("void Set$L($L&& value) {", "}", methodName, templateParam, () -> { writer.write("$LHasBeenSet = true;", fieldName); writer.write("$L = std::forward<$L>(value);", fieldName, templateParam); }); writer.write("template ", templateParam, cppType); - writer.openBlock("$L& With$L($L&& value) {", "}", className, memberName, templateParam, () -> { - writer.write("Set$L(std::forward<$L>(value));", memberName, templateParam); + writer.openBlock("$L& With$L($L&& value) {", "}", className, methodName, templateParam, () -> { + writer.write("Set$L(std::forward<$L>(value));", methodName, templateParam); writer.write("return *this;"); }); if (targetShape.isListShape()) { Shape elementShape = model.expectShape( targetShape.asListShape().get().getMember().getTarget()); - String elementType = CppTypeMapper.getCppType(elementShape, model); - if (elementShape.isEnumShape()) { - writer.openBlock("inline $L& Add$L($L value) {", "}", className, memberName, elementType, () -> { + String elementType = CppTypeMapper.getCppType(elementShape, model, wideIntegers); + if (isByValueType(elementShape)) { + writer.openBlock("inline $L& Add$L($L value) {", "}", className, methodName, elementType, () -> { writer.write("$LHasBeenSet = true;", fieldName); writer.write("$L.push_back(value);", fieldName); writer.write("return *this;"); }); } else { writer.write("template ", templateParam, elementType); - writer.openBlock("$L& Add$L($L&& value) {", "}", className, memberName, templateParam, () -> { + writer.openBlock("$L& Add$L($L&& value) {", "}", className, methodName, templateParam, () -> { writer.write("$LHasBeenSet = true;", fieldName); writer.write("$L.emplace_back(std::forward<$L>(value));", fieldName, templateParam); writer.write("return *this;"); @@ -157,16 +239,27 @@ private static void renderMembers(CppWriter writer, StructureShape shape, targetShape.asMapShape().get().getKey().getTarget()); Shape valueShape = model.expectShape( targetShape.asMapShape().get().getValue().getTarget()); - String keyType = CppTypeMapper.getCppType(keyShape, model); - String valueType = CppTypeMapper.getCppType(valueShape, model); - String keyParam = memberName + "KeyT"; - String valueParam = memberName + "ValueT"; - writer.write("template ", keyParam, keyType, valueParam, valueType); - writer.openBlock("$L& Add$L($L&& key, $L&& value) {", "}", className, memberName, keyParam, valueParam, () -> { - writer.write("$LHasBeenSet = true;", fieldName); - writer.write("$L.emplace(std::forward<$L>(key), std::forward<$L>(value));", fieldName, keyParam, valueParam); - writer.write("return *this;"); - }); + String keyType = CppTypeMapper.getCppType(keyShape, model, wideIntegers); + String valueType = CppTypeMapper.getCppType(valueShape, model, wideIntegers); + // C2J uses a templated perfect-forwarding Add only when BOTH key and value + // are non-primitive AND non-enum; otherwise a plain by-value Add. + boolean bothForwardable = !isByValueType(keyShape) && !isByValueType(valueShape); + if (bothForwardable) { + String keyParam = methodName + "KeyT"; + String valueParam = methodName + "ValueT"; + writer.write("template ", keyParam, keyType, valueParam, valueType); + writer.openBlock("$L& Add$L($L&& key, $L&& value) {", "}", className, methodName, keyParam, valueParam, () -> { + writer.write("$LHasBeenSet = true;", fieldName); + writer.write("$L.emplace(std::forward<$L>(key), std::forward<$L>(value));", fieldName, keyParam, valueParam); + writer.write("return *this;"); + }); + } else { + writer.openBlock("inline $L& Add$L($L key, $L value) {", "}", className, methodName, keyType, valueType, () -> { + writer.write("$LHasBeenSet = true;", fieldName); + writer.write("$L.emplace(key, value);", fieldName); + writer.write("return *this;"); + }); + } } } @@ -190,29 +283,33 @@ private static void renderMembers(CppWriter writer, StructureShape shape, * @param shape the structure shape whose members to render * @param model the model (for resolving member targets) */ - public static void renderPrivateSection(CppWriter writer, StructureShape shape, Model model) { - renderPrivateDataMembers(writer, shape, model); + public static void renderPrivateSection(CppWriter writer, Shape shape, Model model) { + renderPrivateSection(writer, shape, model, false); + } + + /** + * Like {@link #renderPrivateSection(CppWriter, Shape, Model)} but widens {@code integer} + * data members to {@code int64_t} when {@code wideIntegers} is set (CBOR sub-objects). + */ + public static void renderPrivateSection(CppWriter writer, Shape shape, Model model, boolean wideIntegers) { + renderPrivateDataMembers(writer, shape, model, wideIntegers); renderPrivateHasBeenSetFlags(writer, shape, model); } /** * Writes only the data member declarations (with blank lines between each). */ - public static void renderPrivateDataMembers(CppWriter writer, StructureShape shape, Model model) { + public static void renderPrivateDataMembers(CppWriter writer, Shape shape, Model model) { + renderPrivateDataMembers(writer, shape, model, false); + } + + /** Data member declarations, widening {@code integer} to {@code int64_t} when requested. */ + public static void renderPrivateDataMembers(CppWriter writer, Shape shape, Model model, boolean wideIntegers) { java.util.List> entries = new java.util.ArrayList<>(shape.getAllMembers().entrySet()); for (int i = 0; i < entries.size(); i++) { Map.Entry entry = entries.get(i); - String memberName = entry.getKey(); - MemberShape member = entry.getValue(); - Shape targetShape = model.expectShape(member.getTarget()); - String cppType = CppTypeMapper.getCppType(targetShape, model); - String fieldName = "m_" + decapitalize(memberName); - - CppTypeMapper.getDefaultValue(targetShape).ifPresentOrElse( - defaultVal -> writer.write("$L $L{$L};", cppType, fieldName, defaultVal), - () -> writer.write("$L $L;", cppType, fieldName) - ); + writeDataMember(writer, entry.getValue(), entry.getKey(), model, wideIntegers); if (i < entries.size() - 1) { writer.write(""); } @@ -222,19 +319,63 @@ public static void renderPrivateDataMembers(CppWriter writer, StructureShape sha /** * Writes only the HasBeenSet boolean flags (one per member, no blank lines between). */ - public static void renderPrivateHasBeenSetFlags(CppWriter writer, StructureShape shape, Model model) { + public static void renderPrivateHasBeenSetFlags(CppWriter writer, Shape shape, Model model) { for (Map.Entry entry : shape.getAllMembers().entrySet()) { - String memberName = entry.getKey(); - String fieldName = "m_" + decapitalize(memberName); - writer.write("bool $LHasBeenSet = false;", fieldName); + writeHasBeenSetFlag(writer, entry.getValue(), entry.getKey()); } } + /** + * Writes a single private data member declaration. {@code @idempotencyToken} members are + * brace-initialized with {@code Aws::Utils::UUID::PseudoRandomUUID()} so a caller who omits + * the token still gets idempotent behavior; other members fall back to their type's default + * initializer (or none). Matches C2J's ServiceClientModelHeaderMemberDeclaration.vm. + */ + private static void writeDataMember(CppWriter writer, MemberShape member, String memberName, Model model, + boolean wideIntegers) { + Shape targetShape = model.expectShape(member.getTarget()); + String cppType = CppTypeMapper.getCppType(targetShape, model, wideIntegers); + String fieldName = "m_" + decapitalize(memberName); + if (member.hasTrait(IdempotencyTokenTrait.class)) { + writer.write("$L $L{Aws::Utils::UUID::PseudoRandomUUID()};", cppType, fieldName); + return; + } + CppTypeMapper.getDefaultValue(targetShape).ifPresentOrElse( + defaultVal -> writer.write("$L $L{$L};", cppType, fieldName, defaultVal), + () -> writer.write("$L $L;", cppType, fieldName) + ); + } + + /** + * Writes a single HasBeenSet flag. {@code @idempotencyToken} members default to {@code true} + * because they are auto-populated at construction; all others default to {@code false}. + * Matches C2J's ModelClassMembersAndInlines.vm. + */ + private static void writeHasBeenSetFlag(CppWriter writer, MemberShape member, String memberName) { + String fieldName = "m_" + decapitalize(memberName); + boolean initialValue = member.hasTrait(IdempotencyTokenTrait.class); + writer.write("bool $LHasBeenSet = $L;", fieldName, initialValue); + } + private static String decapitalize(String name) { if (name.isEmpty()) return name; return Character.toLowerCase(name.charAt(0)) + name.substring(1); } + /** + * True if a container element / map key or value is passed to {@code Add*} by value rather + * than by perfect-forwarding reference. Matches C2J: primitive and enum types are by-value + * (they are cheap and trivially copyable), everything else is forwarded. + */ + private static boolean isByValueType(Shape shape) { + return CppTypeMapper.isPrimitive(shape) || shape.isEnumShape(); + } + + private static String capitalize(String name) { + if (name.isEmpty()) return name; + return Character.toUpperCase(name.charAt(0)) + name.substring(1); + } + private static final String[] UNSUPPORTED_HTML_TAGS = { "", "", "", "" }; @@ -265,7 +406,7 @@ public static void renderClassDocComment(CppWriter writer, Shape shape, String docText = collapseWhitespace(shape.getTrait(DocumentationTrait.class).get().getValue()); String seeAlso = String.format( "

See Also:

AWS API Reference

", - smithyServiceName, version, shape.getId().getName()); + smithyServiceName, version, CppTypeMapper.cppShapeName(shape)); writeDocComment(writer, docText + seeAlso); } else { writer.write("/**"); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ModelGenerator.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ModelGenerator.java index 2a70d3e52c94..7b935207c72b 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ModelGenerator.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ModelGenerator.java @@ -9,6 +9,7 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeClassifier.ClassifiedShapes; import com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers.EnumShapeRenderer; import com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers.EventStreamRenderer; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers.OutgoingEventStreamRenderer; import com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers.RequestRenderer; import com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers.ResultRenderer; import com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers.SubObjectRenderer; @@ -82,6 +83,10 @@ private List buildRenderers(ClassifiedShapes classified) { classified.eventStreamHandlers(), model, service, protocolTraits, namespace, exportMacro, smithyServiceName)); + renderers.add(new OutgoingEventStreamRenderer( + classified.outgoingEventStreams(), model, service, protocolTraits, + namespace, exportMacro, smithyServiceName)); + return renderers; } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ProtocolResolver.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ProtocolResolver.java index 0704643cd3a0..83b86a5c8541 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ProtocolResolver.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ProtocolResolver.java @@ -13,6 +13,7 @@ import software.amazon.smithy.aws.traits.protocols.RestJson1Trait; import software.amazon.smithy.aws.traits.protocols.RestXmlTrait; import software.amazon.smithy.protocol.traits.Rpcv2CborTrait; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.CborProtocolTraits; import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.JsonProtocolTraits; import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.ProtocolTraits; import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.QueryXmlProtocolTraits; @@ -37,9 +38,10 @@ public final class ProtocolResolver { */ public enum Protocol { JSON("Aws::Utils::Json", "Aws::Utils::Json::JsonView", "Aws::Utils::Json::JsonValue", "Jsonize"), + REST_JSON("Aws::Utils::Json", "Aws::Utils::Json::JsonView", "Aws::Utils::Json::JsonValue", "Jsonize"), REST_XML("Aws::Utils::Xml", "const Aws::Utils::Xml::XmlNode&", "void", "AddToNode"), QUERY_XML("Aws::Utils::Xml", "const Aws::Utils::Xml::XmlNode&", "void", "OutputToStream"), - CBOR("Aws::Utils::Json", "Aws::Utils::Json::JsonView", "Aws::Utils::Json::JsonValue", "Jsonize"), + CBOR("Aws::Utils::Cbor", "Aws::Utils::Cbor::CborValue", "Aws::Utils::Cbor::CborValue", "Jsonize"), EC2("Aws::Utils::Xml", "const Aws::Utils::Xml::XmlNode&", "void", "OutputToStream"); private final String serdeNamespace; @@ -74,9 +76,9 @@ public String getSerializeMethodName() { return serializeMethodName; } - /** Returns true if the protocol uses JSON-style serde (JSON or CBOR). */ + /** Returns true if the protocol uses JSON-style serde (JSON or REST_JSON). */ public boolean isJsonLike() { - return this == JSON || this == CBOR; + return this == JSON || this == REST_JSON; } /** Returns true if the protocol uses XML-style serde (REST_XML, QUERY_XML, or EC2). */ @@ -97,7 +99,8 @@ private ProtocolResolver() { *
  • {@code aws.protocols#ec2Query} → EC2
  • *
  • {@code aws.protocols#awsQuery} → QUERY_XML
  • *
  • {@code aws.protocols#restXml} → REST_XML
  • - *
  • Default (restJson1, awsJson1_0, awsJson1_1, or unrecognized) → JSON
  • + *
  • {@code aws.protocols#restJson1} → REST_JSON
  • + *
  • Default (awsJson1_0, awsJson1_1, or unrecognized) → JSON
  • * * * @param service the service shape to resolve @@ -117,7 +120,10 @@ public static Protocol resolve(ServiceShape service, Model model) { if (service.hasTrait(RestXmlTrait.class)) { return Protocol.REST_XML; } - // Default: JSON (covers RestJson1, AwsJson1_0, AwsJson1_1) + if (service.hasTrait(RestJson1Trait.class)) { + return Protocol.REST_JSON; + } + // Default: JSON (covers AwsJson1_0, AwsJson1_1) return Protocol.JSON; } @@ -139,8 +145,10 @@ public static ProtocolTraits traitsFor(Protocol protocol) { } switch (protocol) { case JSON: - case CBOR: + case REST_JSON: return new JsonProtocolTraits(protocol); + case CBOR: + return new CborProtocolTraits(); case REST_XML: return new RestXmlProtocolTraits(); case QUERY_XML: diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SerdeStub.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SerdeStub.java new file mode 100644 index 000000000000..0efd09b7dc20 --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SerdeStub.java @@ -0,0 +1,160 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model; + +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.StructureShape; + +/** + * Generates protocol-specific serde method declarations (header) and empty stub + * implementations (source). The stubs will be replaced by schema-based serde. + */ +public final class SerdeStub { + + private SerdeStub() { + } + + public static void renderHeaderDeclarations(CppWriter writer, Protocol protocol, + String exportMacro, String className) { + renderHeaderDeclarations(writer, protocol, exportMacro, className, null); + } + + /** + * Emits the protocol-specific serde method declarations for a class. + * + * @param beforeSerializeMethod optional hook run after the (de)serialization constructor + * and {@code operator=} declarations but before the serialize method + * ({@code Jsonize}/{@code AddToNode}/{@code OutputToStream}). Used to inject + * additional constructors (e.g. the event-stream initial-response header ctor) + * at the mainline position. Ignored when {@code null}. + */ + public static void renderHeaderDeclarations(CppWriter writer, Protocol protocol, + String exportMacro, String className, + Runnable beforeSerializeMethod) { + if (protocol.isJsonLike()) { + writer.write("$L $L() = default;", exportMacro, className); + writer.write("$L $L(Aws::Utils::Json::JsonView jsonValue);", exportMacro, className); + writer.write("$L $L& operator=(Aws::Utils::Json::JsonView jsonValue);", exportMacro, className); + if (beforeSerializeMethod != null) { + beforeSerializeMethod.run(); + } + writer.write("$L Aws::Utils::Json::JsonValue Jsonize() const;", exportMacro); + } else if (protocol == Protocol.REST_XML) { + writer.write("$L $L() = default;", exportMacro, className); + writer.write("$L $L(const Aws::Utils::Xml::XmlNode& xmlNode);", exportMacro, className); + writer.write("$L $L& operator=(const Aws::Utils::Xml::XmlNode& xmlNode);", exportMacro, className); + if (beforeSerializeMethod != null) { + beforeSerializeMethod.run(); + } + writer.write("$L void AddToNode(Aws::Utils::Xml::XmlNode& parentNode) const;", exportMacro); + } else if (protocol == Protocol.QUERY_XML || protocol == Protocol.EC2) { + writer.write("$L $L() = default;", exportMacro, className); + writer.write("$L $L(const Aws::Utils::Xml::XmlNode& xmlNode);", exportMacro, className); + writer.write("$L $L& operator=(const Aws::Utils::Xml::XmlNode& xmlNode);", exportMacro, className); + if (beforeSerializeMethod != null) { + beforeSerializeMethod.run(); + } + writer.write("$L void OutputToStream(Aws::OStream& ostream, const char* location, unsigned index, const char* locationValue) const;", exportMacro); + writer.write("$L void OutputToStream(Aws::OStream& ostream, const char* location) const;", exportMacro); + } else { + throw new UnsupportedOperationException("Unsupported protocol for serde header declarations: " + protocol); + } + } + + public static void renderSourceImplementation(CppWriter writer, StructureShape shape, + Model model, Protocol protocol, + String className, String serviceName, + String projectName) { + if (protocol.isJsonLike()) { + renderJsonStub(writer, className); + } else if (protocol == Protocol.REST_XML) { + renderXmlStub(writer, className); + } else if (protocol == Protocol.QUERY_XML || protocol == Protocol.EC2) { + renderQueryXmlStub(writer, className); + } else { + throw new UnsupportedOperationException("Unsupported protocol for serde source implementation: " + protocol); + } + } + + /** + * Emits the empty per-protocol serde source bodies for a class that has no backing + * StructureShape (event stream union / initial response). Mirrors + * {@link #renderSourceImplementation} but keyed only on the class name. + */ + public static void renderSerdeSourceStub(CppWriter writer, Protocol protocol, String className) { + if (protocol.isJsonLike()) { + renderJsonStub(writer, className); + } else if (protocol == Protocol.REST_XML) { + renderXmlStub(writer, className); + } else if (protocol == Protocol.QUERY_XML || protocol == Protocol.EC2) { + renderQueryXmlStub(writer, className); + } else { + throw new UnsupportedOperationException("Unsupported protocol for serde source stub: " + protocol); + } + } + + /** + * Emits a protocol-agnostic stub for an event-stream event case body: a TODO marker + * and a minimal, compilable callback invocation with a default-constructed event. + * No protocol-specific deserialization is emitted. + * + * @param writer the CppWriter + * @param eventShapeName the C++ event shape type (e.g. "SubscribeToShardEvent") + * @param callbackMember the handler callback member (e.g. "m_onSubscribeToShardEvent") + */ + public static void renderEventPayloadDecodeStub(CppWriter writer, String eventShapeName, + String callbackMember) { + writer.write("// TODO: protocol-specific event payload deserialization"); + writer.write("$L($L{});", callbackMember, eventShapeName); + } + + /** + * Emits a protocol-agnostic stub in place of the protocol-specific error-payload parse. + * The header-derived error code/message still flow to MarshallError at the call site. + */ + public static void renderErrorPayloadParseStub(CppWriter writer) { + writer.write("// TODO: protocol-specific error payload deserialization"); + } + + private static void renderJsonStub(CppWriter writer, String className) { + writer.write("$L::$L(JsonView jsonValue) { *this = jsonValue; }", className, className); + writer.write(""); + writer.openBlock("$L& $L::operator=(JsonView jsonValue) {", "}", className, className, () -> { + writer.write("return *this;"); + }); + writer.write(""); + writer.openBlock("JsonValue $L::Jsonize() const {", "}", className, () -> { + writer.write("JsonValue payload;"); + writer.write("return payload;"); + }); + } + + private static void renderXmlStub(CppWriter writer, String className) { + writer.write("$L::$L(const XmlNode& xmlNode) { *this = xmlNode; }", className, className); + writer.write(""); + writer.openBlock("$L& $L::operator=(const XmlNode& xmlNode) {", "}", className, className, () -> { + writer.write("return *this;"); + }); + writer.write(""); + writer.openBlock("void $L::AddToNode(XmlNode& parentNode) const {", "}", className, () -> { + }); + } + + private static void renderQueryXmlStub(CppWriter writer, String className) { + writer.write("$L::$L(const XmlNode& xmlNode) { *this = xmlNode; }", className, className); + writer.write(""); + writer.openBlock("$L& $L::operator=(const XmlNode& xmlNode) {", "}", className, className, () -> { + writer.write("return *this;"); + }); + writer.write(""); + writer.openBlock("void $L::OutputToStream(Aws::OStream& ostream, const char* location, unsigned index, const char* locationValue) const {", "}", className, () -> { + }); + writer.write(""); + writer.openBlock("void $L::OutputToStream(Aws::OStream& ostream, const char* location) const {", "}", className, () -> { + }); + } +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ShapeClassifier.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ShapeClassifier.java index 85c1c6da40af..4b68d03553af 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ShapeClassifier.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ShapeClassifier.java @@ -18,11 +18,13 @@ import software.amazon.smithy.model.shapes.UnionShape; import software.amazon.smithy.model.traits.EnumTrait; import software.amazon.smithy.model.traits.ErrorTrait; +import software.amazon.smithy.model.traits.HttpPayloadTrait; import software.amazon.smithy.model.traits.StreamingTrait; import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -56,8 +58,9 @@ public record RequestInfo(StructureShape shape, OperationShape operation) {} * * @param shape the result structure shape * @param operation the operation shape that uses this as output + * @param streaming true if the result binds a raw streaming httpPayload blob member */ - public record ResultInfo(StructureShape shape, OperationShape operation) {} + public record ResultInfo(StructureShape shape, OperationShape operation, boolean streaming) {} /** * Metadata about an operation whose output contains an event stream. @@ -106,6 +109,9 @@ public static ClassifiedShapes classify(Model model, ServiceShape service, Proto Set inputShapeIds = new HashSet<>(); Set outputShapeIds = new HashSet<>(); + // @streaming unions bound to a request input: rendered as EventEncoderStream subclasses + // (outgoing event streams), not as tagged-union data types. + Set outgoingEventStreamIds = new HashSet<>(); List requests = new ArrayList<>(); List results = new ArrayList<>(); @@ -117,20 +123,31 @@ public static ClassifiedShapes classify(Model model, ServiceShape service, Proto // Collect operation inputs/outputs and identify event stream handlers for (OperationShape op : index.getContainedOperations(service)) { - op.getInput().ifPresent(id -> { - inputShapeIds.add(id); - model.getShape(id).flatMap(Shape::asStructureShape).ifPresent(s -> { - requests.add(new RequestInfo(s, op)); - - // Check if operation has event-stream-bearing result - boolean resultHasEventStream = op.getOutput() - .flatMap(model::getShape) - .flatMap(Shape::asStructureShape) - .map(out -> hasEventStreamMembers(out, model)) - .orElse(false); - if (resultHasEventStream) { - StructureShape resultShape = model.expectShape(op.getOutputShape(), StructureShape.class); - eventStreamHandlers.add(new EventStreamInfo(op.getId().getName(), s, resultShape)); + // Use getInputShape() (not getInput()) so no-input operations, whose input + // target is smithy.api#Unit, still produce a RequestInfo. C2J emits a Request + // class for every operation; the generated client method references it. + ShapeId inputId = op.getInputShape(); + inputShapeIds.add(inputId); + model.getShape(inputId).flatMap(Shape::asStructureShape).ifPresent(s -> { + requests.add(new RequestInfo(s, op)); + + // Check if operation has event-stream-bearing result + boolean resultHasEventStream = op.getOutput() + .flatMap(model::getShape) + .flatMap(Shape::asStructureShape) + .map(out -> hasEventStreamMembers(out, model)) + .orElse(false); + if (resultHasEventStream) { + StructureShape resultShape = model.expectShape(op.getOutputShape(), StructureShape.class); + eventStreamHandlers.add(new EventStreamInfo(op.getId().getName(), s, resultShape)); + } + + // An input-bound @streaming union is an outgoing event stream (encoder). Collect + // it once and record its shape id so the reachable-walk below does not also add + // it to subObjects. + streamingUnionMember(s, model).ifPresent(union -> { + if (outgoingEventStreamIds.add(union.getId())) { + outgoingEventStreams.add(union); } }); }); @@ -138,7 +155,7 @@ public static ClassifiedShapes classify(Model model, ServiceShape service, Proto outputShapeIds.add(id); model.getShape(id).flatMap(Shape::asStructureShape).ifPresent(s -> { if (!hasEventStreamMembers(s, model)) { - results.add(new ResultInfo(s, op)); + results.add(new ResultInfo(s, op, hasRawStreamingPayload(s, model))); } // If has event stream members, result is skipped (handler generated instead) }); @@ -152,6 +169,8 @@ public static ClassifiedShapes classify(Model model, ServiceShape service, Proto // Already classified as request/result above } else if (shape.isEnumShape() || (shape.isStringShape() && shape.hasTrait(EnumTrait.class))) { enums.add(shape); + } else if (outgoingEventStreamIds.contains(id)) { + // Already collected as an outgoing event stream; do not also render as a data union. } else if (shape.hasTrait(ErrorTrait.class)) { if (isModeledException(shape.asStructureShape().get(), protocol)) { subObjects.add(shape); @@ -171,9 +190,11 @@ public static ClassifiedShapes classify(Model model, ServiceShape service, Proto *

    For JSON/CBOR protocols, trivial members are: Message, message. * For XML protocols, trivial members are: Message, message, Code, code. * If the exception has any member not in the trivial set, it is "modeled" - * and should generate as a sub-object. + * and should generate as a sub-object. Also used by {@code EventStreamRenderer} to decide + * whether an event-stream union's exception member is typed as its concrete shape (modeled) + * or the generic {@code Error} wrapper (non-modeled). */ - private static boolean isModeledException(StructureShape shape, Protocol protocol) { + public static boolean isModeledException(StructureShape shape, Protocol protocol) { Set members = shape.getAllMembers().keySet(); Set trivialJson = Set.of("Message", "message"); Set trivialXml = Set.of("Message", "message", "Code", "code"); @@ -183,15 +204,42 @@ private static boolean isModeledException(StructureShape shape, Protocol protoco return members.stream().anyMatch(m -> !trivial.contains(m)); } + /** + * True if the structure has a raw streaming httpPayload member. Matching C2J's + * {@code isStreamingPayloadMember} (CppViewHelper), an {@code @httpPayload} member is a raw + * stream when its target is a blob or string (or is explicitly {@code @streaming}) and it is + * not an event stream — no {@code @streaming} trait is required for blob/string payloads. + */ + private static boolean hasRawStreamingPayload(StructureShape shape, Model model) { + for (MemberShape member : shape.getAllMembers().values()) { + if (!member.hasTrait(HttpPayloadTrait.class) || StreamingTrait.isEventStream(model, member)) { + continue; + } + Shape target = model.expectShape(member.getTarget()); + if (target.isBlobShape() || target.isStringShape() || target.hasTrait(StreamingTrait.class)) { + return true; + } + } + return false; + } + /** * Returns true if the structure has a member targeting a union with the @streaming trait * (i.e., an event stream member). */ private static boolean hasEventStreamMembers(StructureShape shape, Model model) { - return shape.getAllMembers().values().stream().anyMatch(member -> { + return streamingUnionMember(shape, model).isPresent(); + } + + /** Returns the {@code @streaming} union targeted by a member of {@code shape}, if any. */ + private static Optional streamingUnionMember(StructureShape shape, Model model) { + for (MemberShape member : shape.getAllMembers().values()) { Shape target = model.expectShape(member.getTarget()); - return target.isUnionShape() && target.hasTrait(StreamingTrait.class); - }); + if (target.isUnionShape() && target.hasTrait(StreamingTrait.class)) { + return target.asUnionShape(); + } + } + return Optional.empty(); } /** @@ -227,4 +275,54 @@ public static boolean isEventStreamRequestOperation(OperationShape op, Model mod .map(in -> hasEventStreamMembers(in, model)) .orElse(false); } + + /** + * Returns true if the operation's input structure has a raw streaming httpPayload member + * (a blob/string {@code @httpPayload}, or an explicitly {@code @streaming} payload, that is + * not an event stream). Such requests derive from {@code StreamingRequest} in C2J. + * + * @param op the operation + * @param model the Smithy model + * @return true if the operation's input binds a raw streaming payload + */ + public static boolean isRawStreamingPayloadRequest(OperationShape op, Model model) { + return op.getInput() + .flatMap(model::getShape) + .flatMap(Shape::asStructureShape) + .map(in -> hasRawStreamingPayload(in, model)) + .orElse(false); + } + + /** + * Returns the member name of the raw streaming {@code @httpPayload} member of {@code shape}, + * or empty if there is none. Matches the {@link #hasRawStreamingPayload} predicate. + */ + public static Optional rawStreamingPayloadMemberName(StructureShape shape, Model model) { + for (MemberShape member : shape.getAllMembers().values()) { + if (!member.hasTrait(HttpPayloadTrait.class) || StreamingTrait.isEventStream(model, member)) { + continue; + } + Shape target = model.expectShape(member.getTarget()); + if (target.isBlobShape() || target.isStringShape() || target.hasTrait(StreamingTrait.class)) { + return Optional.of(member.getMemberName()); + } + } + return Optional.empty(); + } + + /** + * Returns the name of the member that targets a {@code @streaming} union (the event-stream + * input member), or empty if there is none. Such a member is sent as an encoded event stream + * via {@code GetBody()}, so it is rendered as a {@code std::shared_ptr} rather than a + * value member. + */ + public static Optional eventStreamMemberName(StructureShape shape, Model model) { + for (MemberShape member : shape.getAllMembers().values()) { + Shape target = model.expectShape(member.getTarget()); + if (target.isUnionShape() && target.hasTrait(StreamingTrait.class)) { + return Optional.of(member.getMemberName()); + } + } + return Optional.empty(); + } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraits.java new file mode 100644 index 000000000000..585d3e399577 --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraits.java @@ -0,0 +1,229 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol; + +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.OperationShape; +import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.model.shapes.StructureShape; +import software.amazon.smithy.model.traits.UnitTypeTrait; + +/** + * CBOR (Smithy {@code rpcv2Cbor}) serde rendering. Distinct from the JSON family: it + * uses {@code Aws::Utils::Cbor::CborValue} model/result types, includes the CRT and core + * CBOR headers, and carries its protocol identity through content-type headers rather + * than an {@code X-Amz-Target} header. + */ +public final class CborProtocolTraits implements ProtocolTraits { + + @Override + public Protocol protocol() { + return Protocol.CBOR; + } + + @Override + public String serdeNamespace() { + return Protocol.CBOR.getSerdeNamespace(); + } + + @Override + public boolean widensIntegers() { + return true; + } + + @Override + public void writeShapeForwardDeclarations(CppWriter writer) { + writer.writeNamespaceOpen("Utils"); + writer.writeNamespaceOpen("Cbor"); + writer.write("class CborValue;"); + writer.writeNamespaceClose("Cbor"); + writer.writeNamespaceClose("Utils"); + } + + @Override + public void writeResultForwardDeclarations(CppWriter writer) { + writer.writeNamespaceOpen("Utils"); + writer.writeNamespaceOpen("Cbor"); + writer.write("class CborValue;"); + writer.writeNamespaceClose("Cbor"); + writer.writeNamespaceClose("Utils"); + } + + @Override + public void writeSerdeMethodDecls(CppWriter writer, String exportMacro, String className, + Runnable beforeSerializeMethod) { + // CBOR sub-objects deserialize from a streaming CborDecoder and serialize via CborEncode + // (CborSubObjectHeader.vm), NOT the JSON-family CborValue/Jsonize shape. + writer.write("$L $L() = default;", exportMacro, className); + writer.write("$L $L(const std::shared_ptr& decoder);", exportMacro, className); + writer.write("$L $L& operator=(const std::shared_ptr& decoder);", + exportMacro, className); + if (beforeSerializeMethod != null) { + beforeSerializeMethod.run(); + } + writer.write("$L void CborEncode(Aws::Crt::Cbor::CborEncoder& encoder) const;", exportMacro); + } + + @Override + public void writeResultSerdeDecls(CppWriter writer, String exportMacro, String className) { + writer.write("$L $L(const Aws::AmazonWebServiceResult& result);", + exportMacro, className); + writer.write("$L $L& operator=(const Aws::AmazonWebServiceResult& result);", + exportMacro, className); + } + + @Override + public java.util.List serdeIncludes(FileKind kind) { + switch (kind) { + case RESULT_SOURCE: + return java.util.List.of( + "aws/crt/cbor/Cbor.h", + "aws/core/utils/cbor/CborValue.h", + "aws/core/utils/UnreferencedParam.h", + "aws/core/utils/memory/stl/AWSStringStream.h"); + case INITIAL_RESPONSE_SOURCE: + return java.util.List.of( + "aws/crt/cbor/Cbor.h", + "aws/core/utils/cbor/CborValue.h", + "aws/core/utils/UnreferencedParam.h"); + case REQUEST_SOURCE: + // CborRequestSource.vm: request payloads encode via the streaming CborEncoder, + // so NO DOM header here. + return java.util.List.of("aws/crt/cbor/Cbor.h", "utility"); + case STREAMING_RESULT_SOURCE: + return java.util.List.of(); + case SUBOBJECT_HEADER: + // CborSubObjectHeader.vm hard-includes : the ctor/operator= + // reference Aws::Crt::Cbor::CborDecoder and CborEncode takes a CborEncoder&. + return java.util.List.of("aws/crt/cbor/Cbor.h"); + case RESULT_HEADER: + // CborResultHeader.vm hard-includes as well. + return java.util.List.of("aws/crt/cbor/Cbor.h"); + case SUBOBJECT_SOURCE: + case EVENT_HANDLER_SOURCE: + return java.util.List.of("aws/crt/cbor/Cbor.h", "aws/core/utils/cbor/CborValue.h"); + default: + throw new UnsupportedOperationException( + "No serde includes defined for FileKind " + kind + " in CborProtocolTraits"); + } + } + + @Override + public java.util.List serdeUsings(FileKind kind) { + switch (kind) { + case EVENT_HANDLER_SOURCE: + return java.util.List.of(serdeNamespace()); + case RESULT_SOURCE: + case INITIAL_RESPONSE_SOURCE: + // CborResultSource.vm pulls the full set (result payloads use the CborValue DOM). + return java.util.List.of("Aws::Crt", "Aws::Crt::Cbor", "Aws::Utils", "Aws::Utils::Cbor"); + case REQUEST_SOURCE: + case SUBOBJECT_SOURCE: + // CborRequestSource.vm / CborSubObjectSource.vm: streaming encode/decode only — + // just Aws::Crt::Cbor + Aws::Utils, no Aws::Crt / Aws::Utils::Cbor. + return java.util.List.of("Aws::Crt::Cbor", "Aws::Utils"); + default: + throw new UnsupportedOperationException( + "No serde usings defined for FileKind " + kind + " in CborProtocolTraits"); + } + } + + @Override + public void writeSerdeMethodImpls(CppWriter writer, String className) { + writer.write("$L::$L(const std::shared_ptr& decoder) { *this = decoder; }", + className, className); + writer.write(""); + writer.openBlock("$L& $L::operator=(const std::shared_ptr& decoder) {", "}", + className, className, () -> { + writer.write("AWS_UNREFERENCED_PARAM(decoder);"); + writer.write("return *this;"); + }); + writer.write(""); + writer.openBlock("void $L::CborEncode(Aws::Crt::Cbor::CborEncoder& encoder) const {", "}", className, () -> { + writer.write("size_t mapSize = 0;"); + writer.write("encoder.WriteMapStart(mapSize);"); + }); + } + + @Override + public void writeResultSerdeImpls(CppWriter writer, String className, StructureShape shape, Model model, + String namespace) { + writer.openBlock("$L::$L(const Aws::AmazonWebServiceResult& result) {", "}", + className, className, () -> writer.write("*this = result;")); + writer.write(""); + writer.openBlock("$L& $L::operator=(const Aws::AmazonWebServiceResult& result) {", + "}", className, className, () -> { + writeResultStatusCodeMembers(writer, shape, model); + writer.write("return *this;"); + }); + } + + @Override + public void writeRequestMethodDecls(CppWriter writer, String exportMacro, + StructureShape shape, OperationShape operation, Model model) { + if (emitsSerializePayload(operation, model)) { + writer.write("$L Aws::String SerializePayload() const override;", exportMacro); + } + // CBOR always emits GetRequestSpecificHeaders: it attaches protocol headers + // (content-type / smithy-protocol / accept) regardless of member bindings. + writer.write(""); + writeGetRequestSpecificHeadersDecl(writer, exportMacro); + if (requestHasQueryStringMembers(shape, model)) { + writer.write(""); + writeAddQueryStringParametersDecl(writer, exportMacro); + } + } + + @Override + public void writeRequestMethodImpls(CppWriter writer, String className, + StructureShape shape, OperationShape operation, + ServiceShape service, Model model) { + boolean hasRequest = !operation.getInputShape().equals(UnitTypeTrait.UNIT); + if (emitsSerializePayload(operation, model)) { + if (hasRequest) { + writer.openBlock("Aws::String $L::SerializePayload() const {", "}", className, () -> { + writer.write("Aws::Crt::Cbor::CborEncoder encoder;"); + writer.write(""); + writer.write("// Calculate map size"); + writer.write("size_t mapSize = 0;"); + writer.write(""); + writer.write("encoder.WriteMapStart(mapSize);"); + writer.write(""); + writer.write("const auto str = Aws::String(reinterpret_cast(" + + "encoder.GetEncodedData().ptr), encoder.GetEncodedData().len);"); + writer.write("return str;"); + }); + } else { + writer.write("Aws::String $L::SerializePayload() const { return {}; }", className); + } + writer.write(""); + } + writer.openBlock("Aws::Http::HeaderValueCollection $L::GetRequestSpecificHeaders() const {", "}", + className, () -> { + writer.write("Aws::Http::HeaderValueCollection headers;"); + if (hasRequest) { + writer.write("headers.emplace(Aws::Http::CONTENT_TYPE_HEADER, Aws::CBOR_CONTENT_TYPE);"); + } + writer.write("headers.emplace(Aws::Http::SMITHY_PROTOCOL_HEADER, Aws::RPC_V2_CBOR);"); + writer.write("headers.emplace(Aws::Http::ACCEPT_HEADER, Aws::CBOR_CONTENT_TYPE);"); + writer.write("return headers;"); + }); + if (requestHasQueryStringMembers(shape, model)) { + writer.write(""); + writeAddQueryStringParametersImpl(writer, className); + } + } + + @Override + public void writeStructureEventPayload(CppWriter writer, String msgVar, String valueExpr) { + // CBOR encodes structure/list event payloads via CborEncode, tagged application/cbor. + writer.write("$L.InsertEventHeader(\":content-type\", Aws::String(\"application/cbor\"));", msgVar); + writer.write("Aws::Crt::Cbor::CborEncoder encoder;"); + writer.write("$L.CborEncode(encoder);", valueExpr); + writer.write("$L.WriteEventPayload(encoder.GetEncodedData().ptr, encoder.GetEncodedData().len);", msgVar); + } +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/FileKind.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/FileKind.java new file mode 100644 index 000000000000..cf948248e777 --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/FileKind.java @@ -0,0 +1,28 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol; + +/** + * The kind of generated C++ file whose serde includes / usings are being computed. + * Protocols return different include and using sets per kind (see {@link ProtocolTraits}). + */ +public enum FileKind { + /** Sub-object / structure header (.h). */ + SUBOBJECT_HEADER, + /** Operation-output result header (.h). */ + RESULT_HEADER, + /** Sub-object / structure source (.cpp). */ + SUBOBJECT_SOURCE, + /** Operation-input request source (.cpp). */ + REQUEST_SOURCE, + /** Operation-output result source (.cpp), non-streaming. */ + RESULT_SOURCE, + /** Streaming (raw httpPayload) result source (.cpp) — takes ownership of a ResponseStream. */ + STREAMING_RESULT_SOURCE, + /** Event-stream handler source (.cpp). */ + EVENT_HANDLER_SOURCE, + /** Event-stream InitialResponse source (.cpp). */ + INITIAL_RESPONSE_SOURCE +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraits.java index 5d2bb4ad8289..d5d7ae537fd0 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraits.java @@ -6,20 +6,25 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.OperationShape; +import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.model.shapes.StructureShape; /** - * JSON-flavored serde rendering. Serves both {@link Protocol#JSON} and - * {@link Protocol#CBOR}, which share an identical C++ surface today (CBOR reuses the - * JSON model types and differs only on the wire). + * JSON-flavored serde rendering. Serves {@link Protocol#JSON} (awsJson-RPC) and + * {@link Protocol#REST_JSON} (rest-json), which share an identical C++ serde surface and + * differ only on whether they attach an {@code X-Amz-Target} header. CBOR has its own + * {@link CborProtocolTraits}. */ public final class JsonProtocolTraits implements ProtocolTraits { private final Protocol protocol; public JsonProtocolTraits(Protocol protocol) { - if (protocol != Protocol.JSON && protocol != Protocol.CBOR) { + if (protocol != Protocol.JSON && protocol != Protocol.REST_JSON) { throw new IllegalArgumentException( - "JsonProtocolTraits only serves JSON and CBOR, got: " + protocol); + "JsonProtocolTraits only serves JSON and REST_JSON, got: " + protocol); } this.protocol = protocol; } @@ -75,14 +80,48 @@ public void writeResultSerdeDecls(CppWriter writer, String exportMacro, String c } @Override - public void writeSerdeInclude(CppWriter writer) { - writer.write("#include "); + public java.util.List serdeIncludes(FileKind kind) { + switch (kind) { + case RESULT_SOURCE: + return java.util.List.of( + "aws/core/utils/json/JsonSerializer.h", + "aws/core/utils/UnreferencedParam.h", + "aws/core/utils/memory/stl/AWSStringStream.h"); + case INITIAL_RESPONSE_SOURCE: + return java.util.List.of( + "aws/core/utils/json/JsonSerializer.h", + "aws/core/utils/UnreferencedParam.h"); + case REQUEST_SOURCE: + return java.util.List.of("aws/core/utils/json/JsonSerializer.h", "utility"); + case STREAMING_RESULT_SOURCE: + return java.util.List.of(); + case SUBOBJECT_HEADER: + case RESULT_HEADER: + // Sub-object and result headers forward-declare JsonValue/JsonView; no serializer include. + return java.util.List.of(); + case SUBOBJECT_SOURCE: + case EVENT_HANDLER_SOURCE: + return java.util.List.of("aws/core/utils/json/JsonSerializer.h"); + default: + throw new UnsupportedOperationException( + "No serde includes defined for FileKind " + kind + " in JsonProtocolTraits"); + } } @Override - public void writeSerdeUsingDeclarations(CppWriter writer) { - writer.write("using namespace Aws::Utils::Json;"); - writer.write("using namespace Aws::Utils;"); + public java.util.List serdeUsings(FileKind kind) { + switch (kind) { + case EVENT_HANDLER_SOURCE: + return java.util.List.of(serdeNamespace()); + case RESULT_SOURCE: + case INITIAL_RESPONSE_SOURCE: + case REQUEST_SOURCE: + case SUBOBJECT_SOURCE: + return java.util.List.of("Aws::Utils::Json", "Aws::Utils"); + default: + throw new UnsupportedOperationException( + "No serde usings defined for FileKind " + kind + " in JsonProtocolTraits"); + } } @Override @@ -100,11 +139,57 @@ public void writeSerdeMethodImpls(CppWriter writer, String className) { } @Override - public void writeResultSerdeImpls(CppWriter writer, String className) { + public void writeResultSerdeImpls(CppWriter writer, String className, StructureShape shape, Model model, + String namespace) { writer.openBlock("$L::$L(const Aws::AmazonWebServiceResult& result) {", "}", className, className, () -> writer.write("*this = result;")); writer.write(""); writer.openBlock("$L& $L::operator=(const Aws::AmazonWebServiceResult& result) {", "}", - className, className, () -> writer.write("return *this;")); + className, className, () -> { + writeResultStatusCodeMembers(writer, shape, model); + writer.write("return *this;"); + }); + } + + @Override + public boolean hasTargetHeader() { + // awsJson1_0 / awsJson1_1 send X-Amz-Target; rest-json and CBOR do not. + return protocol == Protocol.JSON; + } + + @Override + public void writeRequestMethodDecls(CppWriter writer, String exportMacro, + StructureShape shape, OperationShape operation, Model model) { + // A raw-streaming-payload request sends its body via the streaming base class, so no + // SerializePayload is emitted (matches C2J). + if (emitsSerializePayload(operation, model)) { + writer.write("$L Aws::String SerializePayload() const override;", exportMacro); + } + if (hasTargetHeader() || requestHasHeaderMembers(shape, model)) { + writer.write(""); + writeGetRequestSpecificHeadersDecl(writer, exportMacro); + } + if (requestHasQueryStringMembers(shape, model)) { + writer.write(""); + writeAddQueryStringParametersDecl(writer, exportMacro); + } + } + + @Override + public void writeRequestMethodImpls(CppWriter writer, String className, + StructureShape shape, OperationShape operation, + ServiceShape service, Model model) { + if (emitsSerializePayload(operation, model)) { + String payloadBody = protocol == Protocol.JSON ? "\"{}\"" : "{}"; + writer.write("Aws::String $L::SerializePayload() const { return $L; }", className, payloadBody); + } + if (hasTargetHeader() || requestHasHeaderMembers(shape, model)) { + writer.write(""); + writeGetRequestSpecificHeadersImpl(writer, className, shape, operation, service, model); + } + if (requestHasQueryStringMembers(shape, model)) { + writer.write(""); + writeAddQueryStringParametersImpl(writer, className); + } } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraits.java index bd9fda2bac43..5384d25bb484 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraits.java @@ -6,6 +6,16 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeClassifier; +import software.amazon.smithy.model.Model; +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.StructureShape; +import software.amazon.smithy.model.traits.HttpHeaderTrait; +import software.amazon.smithy.model.traits.HttpPrefixHeadersTrait; +import software.amazon.smithy.model.traits.HttpQueryTrait; +import software.amazon.smithy.model.traits.HttpQueryParamsTrait; /** * Owns every protocol-specific rendering decision for generated model code. @@ -26,6 +36,16 @@ public interface ProtocolTraits { /** C++ namespace holding the serde utilities, e.g. {@code Aws::Utils::Json}. */ String serdeNamespace(); + // ------------------------------------------------------------------ + // Include / using SETS (data-driven; preferred over the write-hooks below) + // ------------------------------------------------------------------ + + /** Protocol-specific serde {@code #include} paths (no angle brackets) for the given file kind. */ + java.util.List serdeIncludes(FileKind kind); + + /** {@code using namespace} targets for the given file kind. */ + java.util.List serdeUsings(FileKind kind); + // ------------------------------------------------------------------ // Header side // ------------------------------------------------------------------ @@ -64,20 +84,154 @@ void writeSerdeMethodDecls(CppWriter writer, String exportMacro, String classNam // Source side // ------------------------------------------------------------------ - /** Emits the {@code #include} for this protocol's serializer header. */ - void writeSerdeInclude(CppWriter writer); - - /** Emits the {@code using namespace} declarations this protocol's serde bodies need. */ - void writeSerdeUsingDeclarations(CppWriter writer); - /** * Emits the serde method bodies matching {@link #writeSerdeMethodDecls}. * Bodies are currently empty stubs pending schema-based serde. */ void writeSerdeMethodImpls(CppWriter writer, String className); - /** Emits the result ctor / {@code operator=} bodies matching {@link #writeResultSerdeDecls}. */ - void writeResultSerdeImpls(CppWriter writer, String className); + /** + * Emits the result ctor / {@code operator=} bodies matching {@link #writeResultSerdeDecls}. + * + * @param namespace the C++ model namespace (e.g. {@code "IAM"}), used for fully-qualified + * log tags in protocols that log during deserialization + */ + void writeResultSerdeImpls(CppWriter writer, String className, StructureShape shape, Model model, + String namespace); + + /** + * Emits the trailing status-code assignment block for every result member carrying the + * {@code @httpResponseCode} trait: {@code m_x = static_cast(result.GetResponseCode());} + * plus its has-been-set flag. Called from inside each protocol's result {@code operator=} + * body, immediately before {@code return *this;}, matching the legacy C2J ordering. + */ + default void writeResultStatusCodeMembers(CppWriter writer, StructureShape shape, Model model) { + for (java.util.Map.Entry entry : shape.getAllMembers().entrySet()) { + if (entry.getValue().hasTrait(software.amazon.smithy.model.traits.HttpResponseCodeTrait.class)) { + String name = entry.getKey(); + String field = "m_" + Character.toLowerCase(name.charAt(0)) + name.substring(1); + writer.write("$L = static_cast(result.GetResponseCode());", field); + writer.write("$LHasBeenSet = true;", field); + } + } + } + + // ------------------------------------------------------------------ + // Request (operation input) contract + // ------------------------------------------------------------------ + + /** + * Emits the request-specific serialization method declarations for an + * operation-input class, matching the legacy C2J contract for this protocol family: + *

      + *
    • JSON / REST-JSON: {@code SerializePayload()} plus {@code GetRequestSpecificHeaders()}
    • + *
    • REST-XML: {@code SerializePayload()} only
    • + *
    • Query / EC2: {@code SerializePayload()} plus {@code DumpBodyToUrl(Aws::Http::URI&)}
    • + *
    + * The caller has already emitted {@code GetServiceRequestName} and any event-stream + * accessors; this fills in the wire-format contract. + */ + void writeRequestMethodDecls(CppWriter writer, String exportMacro, + StructureShape shape, OperationShape operation, Model model); + + /** + * Emits the request-specific serialization method bodies matching + * {@link #writeRequestMethodDecls}. Payload bodies are currently empty stubs pending + * schema-based serde; {@code DumpBodyToUrl} / {@code GetRequestSpecificHeaders} carry + * their fixed C2J implementations. + */ + void writeRequestMethodImpls(CppWriter writer, String className, + StructureShape shape, OperationShape operation, + ServiceShape service, Model model); + + /** True when this protocol always attaches an {@code X-Amz-Target} header (AWS JSON-RPC). */ + default boolean hasTargetHeader() { + return false; + } + + /** + * Whether {@code integer} members widen to {@code int64_t} (rather than {@code int}) in this + * protocol's sub-object and result headers. C2J does this only for CBOR + * ({@code CORAL_TYPE_TO_CBOR_CPP_TYPE_MAPPING}: {@code integer -> int64_t}, applied where the + * template sets {@code $protocol == "smithy-rpc-v2-cbor"}). Request headers use the shared + * {@code RequestHeader.vm}, which does not widen, so this never affects request members. + */ + default boolean widensIntegers() { + return false; + } + + /** + * Whether result classes for this protocol expose a top-level {@code GetRequestId()} / + * {@code m_requestId} accessor. C2J emits it for every protocol except Query/EC2, + * whose results instead carry the request id inside the injected {@code ResponseMetadata} + * member. Query/EC2 override this to {@code false}. + */ + default boolean resultHasTopLevelRequestId() { + return true; + } + + /** True when any request member binds to an HTTP header (httpHeader / httpPrefixHeaders). */ + default boolean requestHasHeaderMembers(StructureShape shape, Model model) { + for (MemberShape m : shape.getAllMembers().values()) { + if (m.hasTrait(HttpHeaderTrait.class) || m.hasTrait(HttpPrefixHeadersTrait.class)) { + return true; + } + } + return false; + } + + /** True when any request member binds to the query string (httpQuery / httpQueryParams). */ + default boolean requestHasQueryStringMembers(StructureShape shape, Model model) { + for (MemberShape m : shape.getAllMembers().values()) { + if (m.hasTrait(HttpQueryTrait.class) || m.hasTrait(HttpQueryParamsTrait.class)) { + return true; + } + } + return false; + } + + /** + * True when the request should emit a declared {@code SerializePayload()} method through the + * normal path. C2J omits it (RequestHeader.vm keys only on {@code hasStreamMembers()} / + * {@code hasEventStreamMembers()}) for both a raw streaming {@code @httpPayload} member (the + * streaming base class sends the body via {@code GetBody}) and an event-stream input member + * (which gets an inline empty SerializePayload + {@code GetBody()} override rendered by the + * request renderer). The gate is protocol-agnostic, so every protocol shares it. + */ + default boolean emitsSerializePayload(OperationShape operation, Model model) { + return !ShapeClassifier.isRawStreamingPayloadRequest(operation, model) + && !ShapeClassifier.isEventStreamRequestOperation(operation, model); + } + + default void writeGetRequestSpecificHeadersDecl(CppWriter writer, String exportMacro) { + writer.write("$L Aws::Http::HeaderValueCollection GetRequestSpecificHeaders() const override;", exportMacro); + } + + default void writeAddQueryStringParametersDecl(CppWriter writer, String exportMacro) { + writer.write("$L void AddQueryStringParameters(Aws::Http::URI& uri) const override;", exportMacro); + } + + default void writeGetRequestSpecificHeadersImpl(CppWriter writer, String className, + StructureShape shape, OperationShape operation, + ServiceShape service, Model model) { + writer.openBlock("Aws::Http::HeaderValueCollection $L::GetRequestSpecificHeaders() const {", "}", + className, () -> { + writer.write("Aws::Http::HeaderValueCollection headers;"); + if (hasTargetHeader()) { + writer.write("headers.insert(Aws::Http::HeaderValuePair(\"X-Amz-Target\", \"$L.$L\"));", + service.getId().getName(), operation.getId().getName()); + } + writer.write("return headers;"); + }); + } + + default void writeAddQueryStringParametersImpl(CppWriter writer, String className) { + writer.openBlock("void $L::AddQueryStringParameters(Aws::Http::URI& uri) const {", "}", + className, () -> { + writer.write("AWS_UNREFERENCED_PARAM(uri);"); + writer.write("// TODO: serialize httpQuery/httpQueryParams members"); + }); + } // ------------------------------------------------------------------ // Protocol-agnostic today; kept here so callers have one place to look. @@ -100,4 +254,17 @@ default void writeEventPayloadDecode(CppWriter writer, String eventShapeName, default void writeErrorPayloadParse(CppWriter writer) { writer.write("// TODO: protocol-specific error payload deserialization"); } + + /** + * Emits the {@code :content-type} header and {@code WriteEventPayload(...)} call for an + * outgoing event whose payload is a structure or list — the only protocol-specific arm of + * event-stream encoding (blob and string payloads write the same way for every protocol). + * Default is JSON ({@code application/json} + {@code Jsonize().View().WriteCompact()}); + * CBOR overrides. {@code msgVar} is the {@code Aws::Utils::Event::Message} local and + * {@code valueExpr} is the C++ expression that yields the event value to serialize. + */ + default void writeStructureEventPayload(CppWriter writer, String msgVar, String valueExpr) { + writer.write("$L.InsertEventHeader(\":content-type\", Aws::String(\"application/json\"));", msgVar); + writer.write("$L.WriteEventPayload($L.Jsonize().View().WriteCompact());", msgVar, valueExpr); + } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/QueryXmlProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/QueryXmlProtocolTraits.java index 26de9170478b..6554108ef069 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/QueryXmlProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/QueryXmlProtocolTraits.java @@ -6,6 +6,10 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.OperationShape; +import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.model.shapes.StructureShape; /** * Query-XML serde rendering. Serves both {@link Protocol#QUERY_XML} and @@ -34,6 +38,13 @@ public String serdeNamespace() { return protocol.getSerdeNamespace(); } + @Override + public boolean resultHasTopLevelRequestId() { + // Query/EC2 results carry the request id inside the injected ResponseMetadata member, + // so there is no top-level GetRequestId / m_requestId. + return false; + } + @Override public void writeShapeForwardDeclarations(CppWriter writer) { writer.writeNamespaceOpen("Utils"); @@ -75,14 +86,53 @@ public void writeResultSerdeDecls(CppWriter writer, String exportMacro, String c } @Override - public void writeSerdeInclude(CppWriter writer) { - writer.write("#include "); + public java.util.List serdeIncludes(FileKind kind) { + switch (kind) { + case SUBOBJECT_HEADER: + return java.util.List.of("aws/core/utils/memory/stl/AWSStreamFwd.h"); + case RESULT_HEADER: + // Query/EC2 result headers forward-declare XmlDocument; no serde include. + return java.util.List.of(); + case RESULT_SOURCE: + return java.util.List.of( + "aws/core/utils/xml/XmlSerializer.h", + "aws/core/utils/logging/LogMacros.h"); + case INITIAL_RESPONSE_SOURCE: + return java.util.List.of( + "aws/core/utils/xml/XmlSerializer.h", + "aws/core/utils/UnreferencedParam.h"); + case REQUEST_SOURCE: + return java.util.List.of( + "aws/core/utils/StringUtils.h", + "aws/core/utils/memory/stl/AWSStringStream.h"); + case STREAMING_RESULT_SOURCE: + return java.util.List.of(); + case SUBOBJECT_SOURCE: + case EVENT_HANDLER_SOURCE: + return java.util.List.of("aws/core/utils/xml/XmlSerializer.h"); + default: + throw new UnsupportedOperationException( + "No serde includes defined for FileKind " + kind + " in QueryXmlProtocolTraits"); + } } @Override - public void writeSerdeUsingDeclarations(CppWriter writer) { - writer.write("using namespace Aws::Utils::Xml;"); - writer.write("using namespace Aws::Utils;"); + public java.util.List serdeUsings(FileKind kind) { + switch (kind) { + case RESULT_SOURCE: + return java.util.List.of("Aws::Utils::Xml", "Aws::Utils::Logging", "Aws::Utils"); + case INITIAL_RESPONSE_SOURCE: + return java.util.List.of("Aws::Utils::Xml", "Aws::Utils"); + case REQUEST_SOURCE: + return java.util.List.of("Aws::Utils"); + case EVENT_HANDLER_SOURCE: + return java.util.List.of(serdeNamespace()); + case SUBOBJECT_SOURCE: + return java.util.List.of("Aws::Utils::Xml", "Aws::Utils"); + default: + throw new UnsupportedOperationException( + "No serde usings defined for FileKind " + kind + " in QueryXmlProtocolTraits"); + } } @Override @@ -103,11 +153,87 @@ public void writeSerdeMethodImpls(CppWriter writer, String className) { } @Override - public void writeResultSerdeImpls(CppWriter writer, String className) { + public void writeResultSerdeImpls(CppWriter writer, String className, StructureShape shape, Model model, + String namespace) { writer.openBlock("$L::$L(const Aws::AmazonWebServiceResult& result) {", "}", className, className, () -> writer.write("*this = result;")); writer.write(""); writer.openBlock("$L& $L::operator=(const Aws::AmazonWebServiceResult& result) {", "}", - className, className, () -> writer.write("return *this;")); + className, className, () -> { + writer.write("m_HttpResponseCode = result.GetResponseCode();"); + writer.write("const XmlDocument& xmlDocument = result.GetPayload();"); + writer.write("XmlNode rootNode = xmlDocument.GetRootElement();"); + writer.write("// TODO: protocol-specific body member deserialization"); + // Query extracts ; EC2 extracts a top-level . Both + // populate m_responseMetadata; rest-xml/json/cbor do neither. + if (protocol == Protocol.EC2) { + writer.openBlock("if (!rootNode.IsNull()) {", "}", () -> { + writer.write("XmlNode requestIdNode = rootNode.FirstChild(\"requestId\");"); + writer.openBlock("if (!requestIdNode.IsNull()) {", "}", () -> { + writer.write("m_responseMetadata.SetRequestId(StringUtils::Trim(requestIdNode.GetText().c_str()));"); + writer.write("m_responseMetadataHasBeenSet = true;"); + }); + }); + } else { + writer.openBlock("if (!rootNode.IsNull()) {", "}", () -> { + writer.write("XmlNode responseMetadataNode = rootNode.FirstChild(\"ResponseMetadata\");"); + writer.write("m_responseMetadata = responseMetadataNode;"); + writer.write("m_responseMetadataHasBeenSet = true;"); + writer.write("AWS_LOGSTREAM_DEBUG(\"Aws::$L::Model::$L\", " + + "\"x-amzn-request-id: \" << m_responseMetadata.GetRequestId());", + namespace, className); + }); + } + writeResultStatusCodeMembers(writer, shape, model); + writer.write("return *this;"); + }); + } + + @Override + public void writeRequestMethodDecls(CppWriter writer, String exportMacro, + StructureShape shape, OperationShape operation, Model model) { + if (emitsSerializePayload(operation, model)) { + writer.write("$L Aws::String SerializePayload() const override;", exportMacro); + } + if (requestHasHeaderMembers(shape, model)) { + writer.write(""); + writeGetRequestSpecificHeadersDecl(writer, exportMacro); + } + if (requestHasQueryStringMembers(shape, model)) { + writer.write(""); + writeAddQueryStringParametersDecl(writer, exportMacro); + } + writer.write(""); + // DumpBodyToUrl is a protected virtual in AmazonWebServiceRequest, so the override + // is bracketed under protected: and the section restored to public: afterwards, + // matching the legacy C2J layout. + writer.dedent(); + writer.write("protected:"); + writer.indent(); + writer.write("$L void DumpBodyToUrl(Aws::Http::URI& uri) const override;", exportMacro); + writer.dedent(); + writer.write(""); + writer.write("public:"); + writer.indent(); + } + + @Override + public void writeRequestMethodImpls(CppWriter writer, String className, + StructureShape shape, OperationShape operation, + ServiceShape service, Model model) { + if (emitsSerializePayload(operation, model)) { + writer.write("Aws::String $L::SerializePayload() const { return {}; }", className); + } + if (requestHasHeaderMembers(shape, model)) { + writer.write(""); + writeGetRequestSpecificHeadersImpl(writer, className, shape, operation, service, model); + } + if (requestHasQueryStringMembers(shape, model)) { + writer.write(""); + writeAddQueryStringParametersImpl(writer, className); + } + writer.write(""); + writer.write("void $L::DumpBodyToUrl(Aws::Http::URI& uri) const { uri.SetQueryString(SerializePayload()); }", + className); } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RestXmlProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RestXmlProtocolTraits.java index 06fc3f7cec82..ea657c02a2ef 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RestXmlProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RestXmlProtocolTraits.java @@ -6,6 +6,10 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.OperationShape; +import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.model.shapes.StructureShape; /** * REST-XML serde rendering. Shapes serialize by attaching themselves to a parent @@ -62,14 +66,47 @@ public void writeResultSerdeDecls(CppWriter writer, String exportMacro, String c } @Override - public void writeSerdeInclude(CppWriter writer) { - writer.write("#include "); + public java.util.List serdeIncludes(FileKind kind) { + switch (kind) { + case RESULT_SOURCE: + return java.util.List.of( + "aws/core/utils/xml/XmlSerializer.h", + "aws/core/utils/memory/stl/AWSStringStream.h"); + case INITIAL_RESPONSE_SOURCE: + return java.util.List.of( + "aws/core/utils/xml/XmlSerializer.h", + "aws/core/utils/UnreferencedParam.h"); + case REQUEST_SOURCE: + return java.util.List.of("aws/core/utils/xml/XmlSerializer.h", "utility"); + case STREAMING_RESULT_SOURCE: + return java.util.List.of(); + case SUBOBJECT_HEADER: + case RESULT_HEADER: + // Sub-object and result headers forward-declare XmlNode/XmlDocument; no serializer include. + return java.util.List.of(); + case SUBOBJECT_SOURCE: + case EVENT_HANDLER_SOURCE: + return java.util.List.of("aws/core/utils/xml/XmlSerializer.h"); + default: + throw new UnsupportedOperationException( + "No serde includes defined for FileKind " + kind + " in RestXmlProtocolTraits"); + } } @Override - public void writeSerdeUsingDeclarations(CppWriter writer) { - writer.write("using namespace Aws::Utils::Xml;"); - writer.write("using namespace Aws::Utils;"); + public java.util.List serdeUsings(FileKind kind) { + switch (kind) { + case EVENT_HANDLER_SOURCE: + return java.util.List.of(serdeNamespace()); + case RESULT_SOURCE: + case INITIAL_RESPONSE_SOURCE: + case REQUEST_SOURCE: + case SUBOBJECT_SOURCE: + return java.util.List.of("Aws::Utils::Xml", "Aws::Utils"); + default: + throw new UnsupportedOperationException( + "No serde usings defined for FileKind " + kind + " in RestXmlProtocolTraits"); + } } @Override @@ -85,11 +122,48 @@ public void writeSerdeMethodImpls(CppWriter writer, String className) { } @Override - public void writeResultSerdeImpls(CppWriter writer, String className) { + public void writeResultSerdeImpls(CppWriter writer, String className, StructureShape shape, Model model, + String namespace) { writer.openBlock("$L::$L(const Aws::AmazonWebServiceResult& result) {", "}", className, className, () -> writer.write("*this = result;")); writer.write(""); writer.openBlock("$L& $L::operator=(const Aws::AmazonWebServiceResult& result) {", "}", - className, className, () -> writer.write("return *this;")); + className, className, () -> { + writeResultStatusCodeMembers(writer, shape, model); + writer.write("return *this;"); + }); + } + + @Override + public void writeRequestMethodDecls(CppWriter writer, String exportMacro, + StructureShape shape, OperationShape operation, Model model) { + if (emitsSerializePayload(operation, model)) { + writer.write("$L Aws::String SerializePayload() const override;", exportMacro); + } + if (requestHasHeaderMembers(shape, model)) { + writer.write(""); + writeGetRequestSpecificHeadersDecl(writer, exportMacro); + } + if (requestHasQueryStringMembers(shape, model)) { + writer.write(""); + writeAddQueryStringParametersDecl(writer, exportMacro); + } + } + + @Override + public void writeRequestMethodImpls(CppWriter writer, String className, + StructureShape shape, OperationShape operation, + ServiceShape service, Model model) { + if (emitsSerializePayload(operation, model)) { + writer.write("Aws::String $L::SerializePayload() const { return {}; }", className); + } + if (requestHasHeaderMembers(shape, model)) { + writer.write(""); + writeGetRequestSpecificHeadersImpl(writer, className, shape, operation, service, model); + } + if (requestHasQueryStringMembers(shape, model)) { + writer.write(""); + writeAddQueryStringParametersImpl(writer, className); + } } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EnumShapeRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EnumShapeRenderer.java index 5e187dcce759..9b004db6dea9 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EnumShapeRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EnumShapeRenderer.java @@ -5,6 +5,7 @@ package com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers; import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.CppTypeMapper; import com.amazonaws.util.awsclientsmithygenerator.generators.model.EnumRenderer; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeRenderer; import software.amazon.smithy.model.shapes.Shape; @@ -32,7 +33,7 @@ public EnumShapeRenderer(List enumShapes, String namespace, @Override public void render(CppWriterDelegator writerDelegator) { for (Shape enumShape : enumShapes) { - String name = enumShape.getId().getName(); + String name = CppTypeMapper.cppShapeName(enumShape); String headerFile = "include/aws/" + smithyServiceName + "/model/" + name + ".h"; writerDelegator.useFileWriter(headerFile, writer -> EnumRenderer.renderHeader(writer, enumShape, namespace, exportMacro, smithyServiceName)); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EventStreamRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EventStreamRenderer.java index da3836bd54b3..9878e45e57b8 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EventStreamRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EventStreamRenderer.java @@ -8,7 +8,9 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; import com.amazonaws.util.awsclientsmithygenerator.generators.model.CppTypeMapper; import com.amazonaws.util.awsclientsmithygenerator.generators.model.MemberRenderer; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.FileKind; import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.ProtocolTraits; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeClassifier; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeClassifier.EventStreamInfo; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeRenderer; import software.amazon.smithy.model.Model; @@ -70,7 +72,7 @@ public void render(CppWriterDelegator writerDelegator) { renderHandlerHeader(writerDelegator, info.operationName(), events); renderHandlerSource(writerDelegator, info.operationName(), events); - renderInitialResponse(writerDelegator, info.operationName()); + renderInitialResponse(writerDelegator, info.operationName(), info.resultShape()); renderEventStreamUnion(writerDelegator, info.operationName(), union, events, exceptions); } } @@ -103,6 +105,21 @@ private String eventShapeName(MemberShape member) { return member.getTarget().getName(); } + /** + * True if an exception member targets a modeled exception (members beyond the trivial + * message/code). C2J types modeled exceptions as their concrete shape (with a model include) + * and non-modeled ones as the generic {@code Error} wrapper. + */ + private boolean isModeledException(MemberShape exc) { + StructureShape target = model.expectShape(exc.getTarget(), StructureShape.class); + return ShapeClassifier.isModeledException(target, protocolTraits.protocol()); + } + + /** The C++ type for an exception member: concrete shape name if modeled, else {@code errorType}. */ + private String exceptionType(MemberShape exc, String errorType) { + return isModeledException(exc) ? exc.getTarget().getName() : errorType; + } + /** The wire member key, e.g. "alpha". */ private String wireKey(MemberShape member) { return member.getMemberName(); @@ -223,14 +240,19 @@ private void renderHandlerSource(CppWriterDelegator writerDelegator, String opNa String fileName = "source/model/" + className + ".cpp"; String tag = opName.toUpperCase() + "_HANDLER_CLASS_TAG"; writerDelegator.useFileWriter(fileName, writer -> { - writer.write("#include "); - writer.write("#include "); - writer.write("#include "); - writer.write("#include ", smithyServiceName, namespace); - writer.write("#include ", smithyServiceName, opName); + // The handler parses event/exception payloads with the protocol's serializer. + List includes = new java.util.ArrayList<>(); + includes.add("aws/core/client/CoreErrors.h"); + includes.add("aws/core/utils/event/EventStreamErrors.h"); + includes.add("aws/core/utils/logging/LogMacros.h"); + includes.add("aws/" + smithyServiceName + "/" + namespace + "ErrorMarshaller.h"); + includes.add("aws/" + smithyServiceName + "/model/" + opName + "Handler.h"); + includes.addAll(protocolTraits.serdeIncludes(FileKind.EVENT_HANDLER_SOURCE)); + IncludeSets.emit(writer, includes); writer.write(""); writer.write("using namespace Aws::$1L::Model;", namespace); writer.write("using namespace Aws::Utils::Event;"); + IncludeSets.emitUsings(writer, protocolTraits.serdeUsings(FileKind.EVENT_HANDLER_SOURCE)); writer.write(""); writer.write("AWS_CORE_API extern const char MESSAGE_LOWER_CASE[];"); writer.write("AWS_CORE_API extern const char MESSAGE_CAMEL_CASE[];"); @@ -410,14 +432,45 @@ private void renderHandlerSource(CppWriterDelegator writerDelegator, String opNa // ---- Initial response / event stream union ------------------------------ - private void renderInitialResponse(CppWriterDelegator writerDelegator, String opName) { + /** + * Builds a synthetic {@code InitialResponse} structure from the result's non-event-stream + * members, mirroring C2J's {@code addEventStreamInitialResponse} (CppClientGenerator). The + * {@code @streaming} union member (the event stream) is excluded. + */ + private StructureShape initialResponseShape(String opName, StructureShape resultShape) { + StructureShape.Builder builder = StructureShape.builder() + .id("com.amazonaws.smithy.synthetic#" + opName + "InitialResponse"); + for (MemberShape member : resultShape.getAllMembers().values()) { + Shape target = model.expectShape(member.getTarget()); + if (target.isUnionShape() && target.hasTrait(StreamingTrait.class)) { + continue; + } + builder.addMember(member.getMemberName(), member.getTarget(), + b -> member.getAllTraits().values().forEach(b::addTrait)); + } + return builder.build(); + } + + private void renderInitialResponse(CppWriterDelegator writerDelegator, String opName, + StructureShape resultShape) { String className = opName + "InitialResponse"; + StructureShape shape = initialResponseShape(opName, resultShape); + boolean hasMembers = !shape.getAllMembers().isEmpty(); String headerFile = "include/aws/" + smithyServiceName + "/model/" + className + ".h"; writerDelegator.useFileWriter(headerFile, writer -> { writer.write("#pragma once"); - writer.write("#include "); - writer.write("#include ", smithyServiceName, namespace); + List includes = new java.util.ArrayList<>(); + includes.add(""); + includes.add(""); + includes.addAll(CppTypeMapper.getIncludesForShape(shape, model, smithyServiceName)); + for (String include : new java.util.TreeSet<>(includes)) { + writer.write("#include $L", include); + } + if (hasMembers) { + writer.write(""); + writer.write("#include "); + } writer.write(""); writer.writeNamespaceOpen("Aws"); protocolTraits.writeShapeForwardDeclarations(writer); @@ -429,6 +482,17 @@ private void renderInitialResponse(CppWriterDelegator writerDelegator, String op // The header-collection ctor sits before the serialize method (mainline ordering). protocolTraits.writeSerdeMethodDecls(writer, exportMacro, className, () -> writer.write("$1L $2L(const Http::HeaderValueCollection& responseHeaders);", exportMacro, className)); + // Accessors + private section for the result's non-streaming members. A memberless + // InitialResponse ends right after its serde decls (no private:), matching C2J. + if (hasMembers) { + boolean wideIntegers = protocolTraits.widensIntegers(); + writer.write(""); + MemberRenderer.renderPublicSection(writer, shape, model, exportMacro, className, wideIntegers); + writer.dedent(); + writer.write("private:"); + writer.indent(); + MemberRenderer.renderPrivateSection(writer, shape, model, wideIntegers); + } }); writer.write(""); writer.writeNamespaceClose("Model"); @@ -438,18 +502,34 @@ private void renderInitialResponse(CppWriterDelegator writerDelegator, String op String sourceFile = "source/model/" + className + ".cpp"; writerDelegator.useFileWriter(sourceFile, writer -> { - protocolTraits.writeSerdeInclude(writer); - writer.write("#include "); - writer.write("#include ", smithyServiceName, className); + List includes = new java.util.ArrayList<>(); + includes.add("aws/core/utils/StringUtils.h"); + includes.add("aws/" + smithyServiceName + "/model/" + className + ".h"); + includes.add("utility"); + includes.addAll(protocolTraits.serdeIncludes(FileKind.INITIAL_RESPONSE_SOURCE)); + // Serde-implementation includes derived from the initial-response members (e.g. + // AWSStringStream.h for the header-bound members), matching C2J computeSourceIncludes. + includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, model, smithyServiceName)); + IncludeSets.emit(writer, includes); writer.write(""); - writer.write("using namespace Aws::$1L::Model;", namespace); - protocolTraits.writeSerdeUsingDeclarations(writer); + IncludeSets.emitUsings(writer, protocolTraits.serdeUsings(FileKind.INITIAL_RESPONSE_SOURCE)); + writer.write(""); + // The serde impls are wrapped in an explicit namespace block (not a `using`), + // matching C2J, which renders InitialResponse via the sub-object source template. + writer.writeNamespaceOpen("Aws"); + writer.writeNamespaceOpen(namespace); + writer.writeNamespaceOpen("Model"); writer.write(""); protocolTraits.writeSerdeMethodImpls(writer, className); writer.write(""); - writer.openBlock("$1L::$1L(const Http::HeaderValueCollection& responseHeaders) {", "}", className, () -> { - writer.write("AWS_UNREFERENCED_PARAM(responseHeaders);"); - }); + // Delegate to the default ctor so all members are value-initialized before the + // header-derived ones are set (matches C2J). + writer.openBlock("$1L::$1L(const Http::HeaderValueCollection& responseHeaders) : $1L() {", "}", + className, () -> writer.write("AWS_UNREFERENCED_PARAM(responseHeaders);")); + writer.write(""); + writer.writeNamespaceClose("Model"); + writer.writeNamespaceClose(namespace); + writer.writeNamespaceClose("Aws"); }); } @@ -463,10 +543,18 @@ private void renderEventStreamUnion(CppWriterDelegator writerDelegator, String o writerDelegator.useFileWriter(headerFile, writer -> { writer.write("#pragma once"); writer.write("#include ", smithyServiceName, namespace); - writer.write("#include ", smithyServiceName, namespace); + // C2J omits the service Errors include: its header-include computation skips non-modeled + // exception members (CppViewHelper: `if (next.isException() && !next.isModeledException()) + // continue;`), which are the generic Error wrapper and resolve transitively. + // Concrete event shapes AND modeled exceptions get their own model include. for (MemberShape event : events) { writer.write("#include ", smithyServiceName, eventShapeName(event)); } + for (MemberShape exc : exceptions) { + if (isModeledException(exc)) { + writer.write("#include ", smithyServiceName, exc.getTarget().getName()); + } + } writer.write(""); writer.write("#include "); writer.write(""); @@ -485,9 +573,9 @@ private void renderEventStreamUnion(CppWriterDelegator writerDelegator, String o String cppType = CppTypeMapper.getCppType(model.expectShape(event.getTarget()), model); renderShapeAccessor(writer, className, cppType, event.getMemberName(), event); } - // Exception member accessors, typed as Error. + // Exception member accessors: modeled -> concrete type; non-modeled -> Error. for (MemberShape exc : exceptions) { - renderShapeAccessor(writer, className, errorType, exc.getMemberName(), exc); + renderShapeAccessor(writer, className, exceptionType(exc, errorType), exc.getMemberName(), exc); } writer.dedent(); writer.write("private:"); @@ -498,7 +586,7 @@ private void renderEventStreamUnion(CppWriterDelegator writerDelegator, String o writer.write("$1L $2L;", cppType, "m_" + decapitalize(event.getMemberName())); } for (MemberShape exc : exceptions) { - writer.write("$1L $2L;", errorType, "m_" + decapitalize(exc.getMemberName())); + writer.write("$1L $2L;", exceptionType(exc, errorType), "m_" + decapitalize(exc.getMemberName())); } // HasBeenSet flags for (MemberShape event : events) { diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSets.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSets.java new file mode 100644 index 000000000000..b567172be678 --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSets.java @@ -0,0 +1,93 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers; + +import java.util.ArrayList; +import java.util.List; + +/** + * Universal (non-serde, non-member) {@code #include} paths for each generated file kind. + * Paths are returned without angle brackets; callers add {@code #include <...>}. + * + *

    These are the boilerplate includes that were previously hand-written as string literals + * in each renderer. Serde includes come from {@code ProtocolTraits.serdeIncludes}; member + * includes come from {@code CppTypeMapper.getIncludesForShape}. + */ +final class IncludeSets { + + private IncludeSets() {} + + static List resultHeaderBase(String smithyServiceName, String namespace, + boolean includeAwsString) { + List inc = new ArrayList<>(); + inc.add("aws/core/http/HttpResponse.h"); + inc.add("aws/" + smithyServiceName + "/" + namespace + "_EXPORTS.h"); + if (includeAwsString) { + inc.add("aws/core/utils/memory/stl/AWSString.h"); + } + return inc; + } + + static List streamingResultHeaderBase(String smithyServiceName, String namespace) { + List inc = new ArrayList<>(); + inc.add("aws/core/http/HttpResponse.h"); + inc.add("aws/core/utils/memory/stl/AWSString.h"); + inc.add("aws/core/utils/stream/ResponseStream.h"); + inc.add("aws/" + smithyServiceName + "/" + namespace + "_EXPORTS.h"); + return inc; + } + + static List resultSourceBase(String smithyServiceName, String className) { + List inc = new ArrayList<>(); + inc.add("aws/core/AmazonWebServiceResult.h"); + inc.add("aws/core/utils/StringUtils.h"); + inc.add("aws/" + smithyServiceName + "/model/" + className + ".h"); + inc.add("utility"); + return inc; + } + + static List streamingResultSourceBase(String smithyServiceName, String className) { + List inc = new ArrayList<>(); + inc.add("aws/core/AmazonWebServiceResult.h"); + inc.add("aws/core/utils/StringUtils.h"); + inc.add("aws/core/utils/memory/stl/AWSStringStream.h"); + inc.add("aws/" + smithyServiceName + "/model/" + className + ".h"); + inc.add("utility"); + return inc; + } + + static List requestSourceBase(String smithyServiceName, String className) { + List inc = new ArrayList<>(); + inc.add("aws/" + smithyServiceName + "/model/" + className + ".h"); + // NOTE: is NOT added here. Query/EC2 request sources must not include it, + // and the non-Query protocols' serdeIncludes(REQUEST_SOURCE) already carry . + // Adding it here would force it onto Query. + return inc; + } + + static List subObjectSourceBase(String smithyServiceName, String className) { + List inc = new ArrayList<>(); + inc.add("aws/" + smithyServiceName + "/model/" + className + ".h"); + inc.add("utility"); + return inc; + } + + /** Writes each path as {@code #include }, deduped and sorted (CaseSensitive). */ + static void emit(com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter writer, + List includePaths) { + java.util.TreeSet sorted = new java.util.TreeSet<>(includePaths); + for (String path : sorted) { + writer.write("#include <$L>", path); + } + } + + /** Writes each namespace as {@code using namespace X;} in the given order (not sorted). */ + static void emitUsings(com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter writer, + List namespaces) { + for (String ns : namespaces) { + writer.write("using namespace $L;", ns); + } + } +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/OutgoingEventStreamRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/OutgoingEventStreamRenderer.java new file mode 100644 index 000000000000..b01fcdf80b56 --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/OutgoingEventStreamRenderer.java @@ -0,0 +1,197 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers; + +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.CppTypeMapper; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.MemberRenderer; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeRenderer; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.ProtocolTraits; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.MemberShape; +import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.model.shapes.Shape; +import software.amazon.smithy.model.shapes.StructureShape; +import software.amazon.smithy.model.shapes.UnionShape; +import software.amazon.smithy.model.traits.EventHeaderTrait; +import software.amazon.smithy.model.traits.EventPayloadTrait; + +import java.util.List; +import java.util.Map; + +/** + * Renders outgoing (request-side / bidirectional) event streams: a {@code @streaming} union + * bound to an operation input. C2J emits these header-only as an + * {@code Aws::Utils::Event::EventEncoderStream} subclass with one {@code Write(...)} + * method per union member (EventStreamHeader.vm), rather than as a tagged-union data type. + * + *

    Only the structure/list payload serialization is protocol-specific; that arm is delegated + * to {@link ProtocolTraits#writeStructureEventPayload}. Blob and string payloads write the same + * way for every protocol. + */ +public final class OutgoingEventStreamRenderer implements ShapeRenderer { + + /** How an event's payload is encoded, mirroring C2J's eventPayloadType. */ + private enum PayloadKind { BLOB, STRING, STRUCTURE, NONE } + + private final List outgoingEventStreams; + private final Model model; + private final ServiceShape service; + private final ProtocolTraits protocolTraits; + private final String namespace; + private final String exportMacro; + private final String smithyServiceName; + + public OutgoingEventStreamRenderer(List outgoingEventStreams, Model model, ServiceShape service, + ProtocolTraits protocolTraits, String namespace, String exportMacro, + String smithyServiceName) { + this.outgoingEventStreams = outgoingEventStreams; + this.model = model; + this.service = service; + this.protocolTraits = protocolTraits; + this.namespace = namespace; + this.exportMacro = exportMacro; + this.smithyServiceName = smithyServiceName; + } + + @Override + public void render(CppWriterDelegator writerDelegator) { + for (Shape shape : outgoingEventStreams) { + shape.asUnionShape().ifPresent(union -> renderHeader(writerDelegator, union)); + } + } + + private void renderHeader(CppWriterDelegator writerDelegator, UnionShape union) { + String className = CppTypeMapper.cppShapeName(union); + String fileName = "include/aws/" + smithyServiceName + "/model/" + className + ".h"; + writerDelegator.useFileWriter(fileName, writer -> { + writer.write("#pragma once"); + java.util.Set includes = new java.util.TreeSet<>(); + includes.add(""); + includes.add(""); + includes.add(""); + for (MemberShape event : union.getAllMembers().values()) { + includes.add(""); + } + for (String include : includes) { + writer.write("#include $L", include); + } + writer.write(""); + writer.write("#include "); + writer.write(""); + + writer.writeNamespaceOpen("Aws"); + writer.writeNamespaceOpen(namespace); + writer.writeNamespaceOpen("Model"); + writer.write(""); + MemberRenderer.renderClassDocComment(writer, union, smithyServiceName, service.getVersion()); + writer.openBlock("class $L $L : public Aws::Utils::Event::EventEncoderStream {", "};", + exportMacro, className, () -> { + writer.write("public:"); + writer.write("$L() = default;", className); + writer.write("explicit $L(std::shared_ptr streambuf)", + className); + writer.write(" : Aws::Utils::Event::EventEncoderStream(std::move(streambuf)) {}"); + for (MemberShape event : union.getAllMembers().values()) { + writeEventWriter(writer, className, event); + } + }); + writer.write(""); + writer.writeNamespaceClose("Model"); + writer.writeNamespaceClose(namespace); + writer.writeNamespaceClose("Aws"); + }); + } + + /** Emits one {@code Write(const & value)} method for a union member. */ + private void writeEventWriter(CppWriter writer, String className, MemberShape unionMember) { + String eventShapeName = unionMember.getTarget().getName(); + String wireKey = unionMember.getMemberName(); + StructureShape event = model.expectShape(unionMember.getTarget(), StructureShape.class); + writer.openBlock("$L& Write$L(const $L& value) {", "}", className, eventShapeName, eventShapeName, () -> { + writer.write("Aws::Utils::Event::Message msg;"); + PayloadKind kind = payloadKind(event); + switch (kind) { + case BLOB: { + String getter = "value.Get" + capitalize(requirePayloadMember(event, kind)) + "()"; + writer.openBlock("if (!$L.empty()) {", "}", getter, () -> { + writeEventHeaders(writer, wireKey); + writer.write("msg.InsertEventHeader(\":content-type\", Aws::String(\"application/octet-stream\"));"); + writer.write("msg.WriteEventPayload($L);", getter); + }); + break; + } + case STRING: + writeEventHeaders(writer, wireKey); + writer.write("msg.InsertEventHeader(\":content-type\", Aws::String(\"text/plain\"));"); + writer.write("msg.WriteEventPayload(value.Get$L());", capitalize(requirePayloadMember(event, kind))); + break; + case STRUCTURE: + writeEventHeaders(writer, wireKey); + protocolTraits.writeStructureEventPayload(writer, "msg", "value"); + break; + case NONE: + default: + writeEventHeaders(writer, wireKey); + writer.write("AWS_UNREFERENCED_PARAM(value);"); + break; + } + writer.write("WriteEvent(msg);"); + writer.write("return *this;"); + }); + } + + private void writeEventHeaders(CppWriter writer, String wireKey) { + writer.write("msg.InsertEventHeader(\":message-type\", Aws::String(\"event\"));"); + writer.write("msg.InsertEventHeader(\":event-type\", Aws::String(\"$L\"));", wireKey); + } + + /** + * Determines how an event shape's payload is encoded, mirroring C2J's eventPayloadType logic + * (C2jModelToGeneratorModelTransformer). A single blob/string non-header member serializes as + * that member; a member explicitly marked {@code @eventPayload} likewise; otherwise the event + * structure itself is the payload (structure encoding). + */ + private PayloadKind payloadKind(StructureShape event) { + List> nonHeader = event.getAllMembers().entrySet().stream() + .filter(e -> !e.getValue().hasTrait(EventHeaderTrait.class)) + .collect(java.util.stream.Collectors.toList()); + if (nonHeader.isEmpty()) { + return PayloadKind.NONE; + } + if (nonHeader.size() == 1) { + MemberShape member = nonHeader.get(0).getValue(); + Shape target = model.expectShape(member.getTarget()); + if (target.isStringShape()) { + return PayloadKind.STRING; + } + // A blob member is written as a raw blob only when explicitly @eventPayload; an + // implicit single blob member makes the parent structure the payload (matches C2J). + if (target.isBlobShape() && member.hasTrait(EventPayloadTrait.class)) { + return PayloadKind.BLOB; + } + } + return PayloadKind.STRUCTURE; + } + + /** + * The single non-header payload member name for the blob/string arms. These arms are only + * reached when {@link #payloadKind} found exactly one such member, so absence is a codegen + * bug rather than a modeled state — fail fast. + */ + private String requirePayloadMember(StructureShape event, PayloadKind kind) { + return event.getAllMembers().entrySet().stream() + .filter(e -> !e.getValue().hasTrait(EventHeaderTrait.class)) + .map(Map.Entry::getKey) + .findFirst() + .orElseThrow(() -> new IllegalStateException( + "Event " + event.getId() + " classified as " + kind + " but has no payload member")); + } + + private static String capitalize(String s) { + return s.isEmpty() ? s : Character.toUpperCase(s.charAt(0)) + s.substring(1); + } +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java index 0aa76dd779df..818f3d17b640 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java @@ -8,6 +8,7 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; import com.amazonaws.util.awsclientsmithygenerator.generators.model.CppTypeMapper; import com.amazonaws.util.awsclientsmithygenerator.generators.model.MemberRenderer; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.FileKind; import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.ProtocolTraits; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeClassifier; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeClassifier.RequestInfo; @@ -22,6 +23,7 @@ import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.TreeSet; @@ -59,8 +61,32 @@ public void render(CppWriterDelegator writerDelegator) { } private void renderHeader(CppWriterDelegator writerDelegator, - StructureShape shape, OperationShape operation) { + StructureShape rawShape, OperationShape operation) { String className = operation.getId().getName() + "Request"; + // A request with a raw streaming @httpPayload member derives from StreamingRequest, + // whose base (AmazonStreamingWebServiceRequest) supplies GetBody/SetBody and + // GetContentType/SetContentType, and emits no SerializePayload. Matching C2J: contentType + // is stripped from the model entirely (affects includes AND rendering), while the payload + // member stays for include computation but is skipped in accessor/private rendering. + boolean rawStreamingPayload = ShapeClassifier.isRawStreamingPayloadRequest(operation, model); + // An event-stream (input) member targets a @streaming union: C2J renders it as a + // std::shared_ptr with a collision-renamed getter and an inline empty + // SerializePayload + GetBody() override, so it is excluded from the generic member path. + Optional eventStreamMember = ShapeClassifier.eventStreamMemberName(rawShape, model); + StructureShape includeShape = rawStreamingPayload + ? shapeExcluding(rawShape, Set.of("contentType", "ContentType")) : rawShape; + Set genericExcluded = new java.util.HashSet<>(); + if (rawStreamingPayload) { + // isRawStreamingPayloadRequest guarantees a payload member; absence is a codegen bug. + String payloadMember = ShapeClassifier.rawStreamingPayloadMemberName(rawShape, model) + .orElseThrow(() -> new IllegalStateException( + "Raw streaming payload request without a payload member: " + rawShape.getId())); + genericExcluded.add("contentType"); + genericExcluded.add("ContentType"); + genericExcluded.add(payloadMember); + } + eventStreamMember.ifPresent(genericExcluded::add); + StructureShape shape = genericExcluded.isEmpty() ? rawShape : shapeExcluding(rawShape, genericExcluded); String fileName = "include/aws/" + smithyServiceName + "/model/" + className + ".h"; writerDelegator.useFileWriter(fileName, writer -> { writer.write("#pragma once"); @@ -68,7 +94,11 @@ private void renderHeader(CppWriterDelegator writerDelegator, Set includes = new TreeSet<>(); includes.add(""); includes.add(""); - List memberIncludes = CppTypeMapper.getIncludesForShape(shape, model, smithyServiceName); + // NOTE: request headers do NOT include even when they + // declare URI-taking methods (DumpBodyToUrl / AddQueryStringParameters). The + // base AmazonWebServiceRequest.h forward-declares Aws::Http::URI, which is + // sufficient for a reference parameter, and C2J relies on that forward decl. + List memberIncludes = CppTypeMapper.getIncludesForShape(includeShape, model, smithyServiceName); includes.addAll(memberIncludes); for (String include : includes) { writer.write("#include $L", include); @@ -77,7 +107,12 @@ private void renderHeader(CppWriterDelegator writerDelegator, boolean allPrimitive = shape.getAllMembers().values().stream() .map(m -> model.expectShape(m.getTarget())) .allMatch(CppTypeMapper::isPrimitive); - if (!allPrimitive) { + if (eventStreamMember.isPresent()) { + // The event-stream member is stored as std::shared_ptr. + writer.write(""); + writer.write("#include "); + writer.write("#include "); + } else if (!allPrimitive) { writer.write(""); writer.write("#include "); } @@ -97,7 +132,9 @@ private void renderHeader(CppWriterDelegator writerDelegator, MemberRenderer.renderClassDocComment(writer, shape, smithyServiceName, service.getVersion()); - String baseClass = namespace + "Request"; + // Raw-streaming-payload requests derive from StreamingRequest (a typedef for + // AmazonStreamingWebServiceRequest declared in Request.h), matching C2J. + String baseClass = (rawStreamingPayload ? "Streaming" + namespace : namespace) + "Request"; writer.openBlock("class $L : public $L {", "};", className, baseClass, () -> { writer.write("public:"); writer.write("$L $L() = default;", exportMacro, className); @@ -116,9 +153,15 @@ private void renderHeader(CppWriterDelegator writerDelegator, if (streamingResponse) { writer.write("inline virtual bool HasEventStreamResponse() const override { return true; }"); } - writer.write("$L Aws::String SerializePayload() const override;", exportMacro); - writer.write(""); - writer.write("$L Aws::Http::HeaderValueCollection GetRequestSpecificHeaders() const override;", exportMacro); + if (eventStreamMember.isPresent()) { + // The request body is sent as an encoded event stream via GetBody(), so + // SerializePayload is an inline no-op (matches C2J RequestHeader.vm). + writer.write("// SerializePayload will not be invoked."); + writer.write("// This request is sent by encoding its data in event-streams which is sent as IOStream via GetBody()"); + writer.write("$L Aws::String SerializePayload() const override { return {}; }", exportMacro); + writer.write("$L std::shared_ptr GetBody() const override;", exportMacro); + } + protocolTraits.writeRequestMethodDecls(writer, exportMacro, shape, operation, model); if (streamingResponse) { String handlerType = operation.getId().getName() + "Handler"; @@ -161,20 +204,27 @@ private void renderHeader(CppWriterDelegator writerDelegator, writer.write(""); MemberRenderer.renderPublicSection(writer, shape, model, exportMacro, className); + eventStreamMember.ifPresent(m -> + renderEventStreamMemberAccessor(writer, className, rawShape, m)); - if (!shape.getAllMembers().isEmpty()) { + boolean hasAnyMember = !shape.getAllMembers().isEmpty() || eventStreamMember.isPresent(); + if (hasAnyMember) { writer.dedent(); writer.write("private:"); writer.indent(); if (streamingResponse) { - // Mainline places the handler/decoder after the data members and - // before the HasBeenSet flags. + // Mainline places the event-stream member, then the handler/decoder, after + // the data members and before the HasBeenSet flags. MemberRenderer.renderPrivateDataMembers(writer, shape, model); + eventStreamMember.ifPresent(m -> writer.write("std::shared_ptr<$1L> m_$2L;", + eventStreamUnionType(rawShape, m), decapitalize(m))); String handlerType = operation.getId().getName() + "Handler"; writer.write("$1L m_handler;", handlerType); writer.write("Aws::Utils::Event::EventStreamDecoder m_decoder{Utils::Event::EventStreamDecoder(&m_handler)};"); writer.write(""); MemberRenderer.renderPrivateHasBeenSetFlags(writer, shape, model); + eventStreamMember.ifPresent(m -> + writer.write("bool m_$1LHasBeenSet = false;", decapitalize(m))); } else { MemberRenderer.renderPrivateSection(writer, shape, model); } @@ -191,22 +241,59 @@ private void renderHeader(CppWriterDelegator writerDelegator, private void renderSource(CppWriterDelegator writerDelegator, StructureShape shape, OperationShape operation) { String className = operation.getId().getName() + "Request"; + Optional eventStreamMember = ShapeClassifier.eventStreamMemberName(shape, model); String fileName = "source/model/" + className + ".cpp"; writerDelegator.useFileWriter(fileName, writer -> { - protocolTraits.writeSerdeInclude(writer); - writer.write("#include ", smithyServiceName, className); - writer.write(""); - writer.write("#include "); + // A request with stream members (a raw @httpPayload blob/string body, or an event-stream + // input) is sent via the request body stream, not a serialized JSON payload. C2J routes + // it through StreamRequestSource.vm: AmazonWebServiceResult.h + the Stream/Utils/Aws + // usings (not the JSON serde header/usings). The event-stream sub-case also defines + // GetBody() returning its encoder member. + boolean streaming = ShapeClassifier.isRawStreamingPayloadRequest(operation, model) + || eventStreamMember.isPresent(); + if (streaming) { + List includes = new java.util.ArrayList<>( + IncludeSets.requestSourceBase(smithyServiceName, className)); + includes.add("aws/core/AmazonWebServiceResult.h"); + includes.add("utility"); + includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, model, smithyServiceName)); + IncludeSets.emit(writer, includes); + writer.write(""); + writer.write("using namespace Aws::$L::Model;", namespace); + writer.write("using namespace Aws::Utils::Stream;"); + writer.write("using namespace Aws::Utils;"); + writer.write("using namespace Aws;"); + writer.write(""); + eventStreamMember.ifPresent(m -> { + writer.write("std::shared_ptr $L::GetBody() const { return m_$L; }", + className, decapitalize(m)); + writer.write(""); + }); + // Header/query method bodies (SerializePayload is gated off for streaming requests). + protocolTraits.writeRequestMethodImpls(writer, className, shape, operation, service, model); + if (hasEndpointContextParams(operation, shape)) { + writer.write(""); + renderEndpointContextParams(writer, className, operation, shape); + } + writer.write(""); + return; + } + + List includes = new java.util.ArrayList<>( + IncludeSets.requestSourceBase(smithyServiceName, className)); + includes.addAll(protocolTraits.serdeIncludes(FileKind.REQUEST_SOURCE)); + // Serde-implementation includes derived from members (HashingUtils.h for blob Base64 + // serde, AWSStringStream.h for header/query members), matching C2J computeSourceIncludes. + includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, model, smithyServiceName)); + IncludeSets.emit(writer, includes); writer.write(""); writer.write("using namespace Aws::$L::Model;", namespace); - protocolTraits.writeSerdeUsingDeclarations(writer); + IncludeSets.emitUsings(writer, protocolTraits.serdeUsings(FileKind.REQUEST_SOURCE)); writer.write(""); - writer.write("Aws::String $L::SerializePayload() const { return \"{}\"; }", className); - writer.write(""); - writer.write("Aws::Http::HeaderValueCollection $L::GetRequestSpecificHeaders() const { return {}; }", className); + protocolTraits.writeRequestMethodImpls(writer, className, shape, operation, service, model); if (hasEndpointContextParams(operation, shape)) { writer.write(""); @@ -216,6 +303,65 @@ private void renderSource(CppWriterDelegator writerDelegator, }); } + /** Builds a copy of {@code shape} with the named members removed (null names are ignored). */ + private StructureShape shapeExcluding(StructureShape shape, Set excluded) { + StructureShape.Builder builder = StructureShape.builder().id(shape.getId()); + shape.getAllTraits().values().forEach(builder::addTrait); + for (MemberShape member : shape.getAllMembers().values()) { + if (excluded.contains(member.getMemberName())) { + continue; + } + builder.addMember(member.getMemberName(), member.getTarget(), + b -> member.getAllTraits().values().forEach(b::addTrait)); + } + return builder.build(); + } + + /** The C++ type name of the {@code @streaming} union targeted by the event-stream member. */ + private String eventStreamUnionType(StructureShape shape, String memberName) { + MemberShape member = shape.getAllMembers().get(memberName); + return member.getTarget().getName(); + } + + /** + * Renders the accessor block for an event-stream (input) member: a {@code std::shared_ptr} + * getter/setter/wither. The getter is renamed to {@code GetMember} because {@code GetBody} + * is reserved by the streaming request base (matches C2J's collision handling). + */ + private void renderEventStreamMemberAccessor(CppWriter writer, String className, + StructureShape shape, String memberName) { + String unionType = eventStreamUnionType(shape, memberName); + String cap = capitalize(memberName); + String field = "m_" + decapitalize(memberName); + String getter = cap.equals("Body") ? "GetMemberBody" : "Get" + cap; + writer.write(""); + writer.write("///@{"); + MemberShape member = shape.getAllMembers().get(memberName); + if (member.getTrait(software.amazon.smithy.model.traits.DocumentationTrait.class).isPresent()) { + MemberRenderer.writeDocComment(writer, MemberRenderer.collapseWhitespace( + member.getTrait(software.amazon.smithy.model.traits.DocumentationTrait.class).get().getValue())); + } + writer.write("$1L std::shared_ptr<$2L> $3L() const { return $4L; }", exportMacro, unionType, getter, field); + writer.openBlock("$1L void Set$2L(const std::shared_ptr<$3L>& value) {", "}", exportMacro, cap, unionType, () -> { + writer.write("$1LHasBeenSet = true;", field); + writer.write("$1L = value;", field); + }); + writer.openBlock("$1L $2L& With$3L(const std::shared_ptr<$4L>& value) {", "}", + exportMacro, className, cap, unionType, () -> { + writer.write("Set$1L(value);", cap); + writer.write("return *this;"); + }); + writer.write("///@}"); + } + + private static String capitalize(String s) { + return s.isEmpty() ? s : Character.toUpperCase(s.charAt(0)) + s.substring(1); + } + + private static String decapitalize(String s) { + return s.isEmpty() ? s : Character.toLowerCase(s.charAt(0)) + s.substring(1); + } + private boolean hasEndpointContextParams(OperationShape operation, StructureShape shape) { if (operation.hasTrait(StaticContextParamsTrait.class)) { return true; diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ResultRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ResultRenderer.java index 726f16d4f9f8..b63b2366c6c5 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ResultRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ResultRenderer.java @@ -7,18 +7,20 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; import com.amazonaws.util.awsclientsmithygenerator.generators.model.CppTypeMapper; import com.amazonaws.util.awsclientsmithygenerator.generators.model.MemberRenderer; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.FileKind; import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.ProtocolTraits; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeClassifier.ResultInfo; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeRenderer; import software.amazon.smithy.model.Model; +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.StructureShape; import software.amazon.smithy.model.traits.DocumentationTrait; +import software.amazon.smithy.model.traits.HttpPayloadTrait; import java.util.List; -import java.util.Set; -import java.util.TreeSet; +import java.util.Map; /** * Renders C++ headers and sources for result (operation output) shapes. @@ -48,9 +50,34 @@ public ResultRenderer(List results, Model model, ServiceShape servic @Override public void render(CppWriterDelegator writerDelegator) { for (ResultInfo resInfo : results) { - renderHeader(writerDelegator, resInfo.shape(), resInfo.operation()); - renderSource(writerDelegator, resInfo.shape(), resInfo.operation()); + if (resInfo.streaming()) { + renderStreamingHeader(writerDelegator, resInfo.shape(), resInfo.operation()); + renderStreamingSource(writerDelegator, resInfo.shape(), resInfo.operation()); + } else { + renderHeader(writerDelegator, resInfo.shape(), resInfo.operation()); + renderSource(writerDelegator, resInfo.shape(), resInfo.operation()); + } + } + } + + /** Returns the name of the {@code @httpPayload} streaming member, or null if none. */ + private String streamingPayloadMemberName(StructureShape shape) { + for (Map.Entry entry : shape.getAllMembers().entrySet()) { + if (entry.getValue().hasTrait(HttpPayloadTrait.class)) { + return entry.getKey(); + } } + return null; + } + + /** {@code m_} + decapitalized member name, e.g. "AudioStream" -> "m_audioStream". */ + private static String fieldName(String memberName) { + return "m_" + Character.toLowerCase(memberName.charAt(0)) + memberName.substring(1); + } + + /** Capitalized member name for accessor methods, e.g. "audioStream" -> "AudioStream". */ + private static String capitalize(String memberName) { + return Character.toUpperCase(memberName.charAt(0)) + memberName.substring(1); } private void renderHeader(CppWriterDelegator writerDelegator, @@ -60,15 +87,17 @@ private void renderHeader(CppWriterDelegator writerDelegator, writerDelegator.useFileWriter(fileName, writer -> { writer.write("#pragma once"); - Set includes = new TreeSet<>(); - includes.add(""); - includes.add(""); - includes.add(""); - List memberIncludes = CppTypeMapper.getIncludesForShape(shape, model, smithyServiceName); - includes.addAll(memberIncludes); - for (String include : includes) { - writer.write("#include $L", include); + // AWSString.h is only needed for the top-level m_requestId; string-typed members + // bring their own include via getIncludesForShape. Matches C2J include hygiene. + List includes = new java.util.ArrayList<>(IncludeSets.resultHeaderBase( + smithyServiceName, namespace, protocolTraits.resultHasTopLevelRequestId())); + for (String memberInc : CppTypeMapper.getIncludesForShape(shape, model, smithyServiceName)) { + includes.add(memberInc.replaceAll("^<|>$", "")); } + // Protocols whose result-header serde types are named in the class signature (CBOR: + // CborValue) add their own header here; JSON/XML forward-declare and add nothing. + includes.addAll(protocolTraits.serdeIncludes(FileKind.RESULT_HEADER)); + IncludeSets.emit(writer, includes); writer.write(""); writer.write("#include "); @@ -93,7 +122,148 @@ private void renderHeader(CppWriterDelegator writerDelegator, protocolTraits.writeResultSerdeDecls(writer, exportMacro, className); writer.write(""); - MemberRenderer.renderPublicSectionForResult(writer, shape, model, exportMacro, className); + MemberRenderer.renderPublicSectionForResult(writer, shape, model, exportMacro, className, + protocolTraits.widensIntegers()); + + boolean topLevelRequestId = protocolTraits.resultHasTopLevelRequestId(); + if (topLevelRequestId) { + writer.write(""); + writer.write("///@{"); + writer.write(""); + writer.write("inline const Aws::String& GetRequestId() const { return m_requestId; }"); + writer.write("template "); + writer.openBlock("void SetRequestId(RequestIdT&& value) {", "}", () -> { + writer.write("m_requestIdHasBeenSet = true;"); + writer.write("m_requestId = std::forward(value);"); + }); + writer.write("template "); + writer.openBlock("$L& WithRequestId(RequestIdT&& value) {", "}", className, () -> { + writer.write("SetRequestId(std::forward(value));"); + writer.write("return *this;"); + }); + writer.write("///@}"); + } + + writer.write("inline Aws::Http::HttpResponseCode GetHttpResponseCode() const { return m_HttpResponseCode; }"); + writer.write(""); + + writer.dedent(); + writer.write("private:"); + writer.indent(); + MemberRenderer.renderPrivateDataMembers(writer, shape, model, protocolTraits.widensIntegers()); + if (topLevelRequestId) { + // The blank line separates the modeled members from the m_requestId group; + // C2J omits it (and m_requestId) for Query/EC2 results. + writer.write(""); + writer.write("Aws::String m_requestId;"); + } + writer.write("Aws::Http::HttpResponseCode m_HttpResponseCode;"); + MemberRenderer.renderPrivateHasBeenSetFlags(writer, shape, model); + if (topLevelRequestId) { + writer.write("bool m_requestIdHasBeenSet = false;"); + } + }); + writer.write(""); + + writer.writeNamespaceClose("Model"); + writer.writeNamespaceClose(namespace); + writer.writeNamespaceClose("Aws"); + }); + } + + private void renderSource(CppWriterDelegator writerDelegator, + StructureShape shape, OperationShape operation) { + String className = operation.getId().getName() + "Result"; + String fileName = "source/model/" + className + ".cpp"; + writerDelegator.useFileWriter(fileName, writer -> { + + List includes = new java.util.ArrayList<>( + IncludeSets.resultSourceBase(smithyServiceName, className)); + includes.addAll(protocolTraits.serdeIncludes(FileKind.RESULT_SOURCE)); + // Serde-implementation includes derived from members (HashingUtils.h for blob Base64 + // serde, AWSStringStream.h for header/query members), matching C2J computeSourceIncludes. + includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, model, smithyServiceName)); + IncludeSets.emit(writer, includes); + writer.write(""); + writer.write("using namespace Aws::$L::Model;", namespace); + IncludeSets.emitUsings(writer, protocolTraits.serdeUsings(FileKind.RESULT_SOURCE)); + writer.write("using namespace Aws;"); + writer.write(""); + + protocolTraits.writeResultSerdeImpls(writer, className, shape, model, namespace); + writer.write(""); + }); + } + + /** + * Renders a streaming result header: a move-only class whose payload is an + * {@code Aws::Utils::Stream::ResponseStream} exposed via {@code GetBody()} / + * {@code ReplaceBody}, matching the legacy C2J {@code StreamResultHeader.vm} output. + */ + private void renderStreamingHeader(CppWriterDelegator writerDelegator, + StructureShape shape, OperationShape operation) { + String className = operation.getId().getName() + "Result"; + String streamMember = streamingPayloadMemberName(shape); + String fileName = "include/aws/" + smithyServiceName + "/model/" + className + ".h"; + writerDelegator.useFileWriter(fileName, writer -> { + writer.write("#pragma once"); + + List includes = new java.util.ArrayList<>( + IncludeSets.streamingResultHeaderBase(smithyServiceName, namespace)); + for (String memberInc : CppTypeMapper.getIncludesForShape(shape, model, smithyServiceName)) { + includes.add(memberInc.replaceAll("^<|>$", "")); + } + IncludeSets.emit(writer, includes); + + writer.write(""); + writer.write("#include "); + writer.write(""); + + writer.writeNamespaceOpen("Aws"); + writer.write("template "); + writer.write("class AmazonWebServiceResult;"); + writer.write(""); + + writer.writeNamespaceOpen(namespace); + writer.writeNamespaceOpen("Model"); + + if (shape.getTrait(DocumentationTrait.class).isPresent()) { + MemberRenderer.renderClassDocComment(writer, shape, smithyServiceName, service.getVersion()); + } + + writer.openBlock("class $L {", "};", className, () -> { + writer.write("public:"); + writer.write("$L $L() = default;", exportMacro, className); + writer.write("$L $L($L&&) = default;", exportMacro, className, className); + writer.write("$L $L& operator=($L&&) = default;", exportMacro, className, className); + writer.write("// we delete these because Microsoft doesn't handle move generation correctly"); + writer.write("// and we therefore don't trust them to get it right here either."); + writer.write("$L(const $L&) = delete;", className, className); + writer.write("$L& operator=(const $L&) = delete;", className, className); + writer.write(""); + writer.write("$L $L(Aws::AmazonWebServiceResult&& result);", + exportMacro, className); + writer.write("$L $L& operator=(Aws::AmazonWebServiceResult&& result);", + exportMacro, className); + writer.write(""); + + // Streaming payload accessors (no Set/With/HasBeenSet for the stream member). + // The getter is named after the member (GetBody, GetAudioStream, GetResponse); + // ReplaceBody stays literal, matching C2J StreamResultHeader.vm. + String streamField = fieldName(streamMember); + writer.write("///@{"); + shape.getMember(streamMember) + .flatMap(m -> m.getTrait(DocumentationTrait.class)) + .ifPresent(doc -> MemberRenderer.writeDocComment(writer, + MemberRenderer.collapseWhitespace(doc.getValue()))); + writer.write("inline Aws::IOStream& Get$L() const { return $L.GetUnderlyingStream(); }", + capitalize(streamMember), streamField); + writer.write("inline void ReplaceBody(Aws::IOStream* body) { " + + "$L = Aws::Utils::Stream::ResponseStream(body); }", streamField); + writer.write("///@}"); + + MemberRenderer.renderPublicSectionForResultExcluding(writer, shape, model, exportMacro, + className, streamMember, protocolTraits.widensIntegers()); writer.write(""); writer.write("///@{"); @@ -117,11 +287,14 @@ private void renderHeader(CppWriterDelegator writerDelegator, writer.dedent(); writer.write("private:"); writer.indent(); - MemberRenderer.renderPrivateDataMembers(writer, shape, model); + writer.write("Aws::Utils::Stream::ResponseStream $L{};", streamField); + MemberRenderer.renderPrivateDataMembersExcluding(writer, shape, model, streamMember, + protocolTraits.widensIntegers()); writer.write(""); writer.write("Aws::String m_requestId;"); writer.write("Aws::Http::HttpResponseCode m_HttpResponseCode;"); - MemberRenderer.renderPrivateHasBeenSetFlags(writer, shape, model); + writer.write("bool $LHasBeenSet = false;", streamField); + MemberRenderer.renderPrivateHasBeenSetFlagsExcluding(writer, shape, model, streamMember); writer.write("bool m_requestIdHasBeenSet = false;"); }); writer.write(""); @@ -132,27 +305,42 @@ private void renderHeader(CppWriterDelegator writerDelegator, }); } - private void renderSource(CppWriterDelegator writerDelegator, - StructureShape shape, OperationShape operation) { + /** + * Renders a streaming result source: the move ctor/assign take ownership of the + * response payload stream ({@code TakeOwnershipOfPayload}) rather than parsing a body. + */ + private void renderStreamingSource(CppWriterDelegator writerDelegator, + StructureShape shape, OperationShape operation) { String className = operation.getId().getName() + "Result"; + String streamField = fieldName(streamingPayloadMemberName(shape)); String fileName = "source/model/" + className + ".cpp"; writerDelegator.useFileWriter(fileName, writer -> { - - writer.write("#include "); - writer.write("#include "); - writer.write("#include "); - protocolTraits.writeSerdeInclude(writer); - writer.write("#include "); - writer.write("#include ", smithyServiceName, className); - writer.write(""); - writer.write("#include "); + List includes = new java.util.ArrayList<>( + IncludeSets.streamingResultSourceBase(smithyServiceName, className)); + includes.addAll(protocolTraits.serdeIncludes(FileKind.STREAMING_RESULT_SOURCE)); + // Serde-implementation includes derived from members (e.g. HashingUtils.h for the + // blob payload member's Base64 serde), matching C2J computeSourceIncludes. + includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, model, smithyServiceName)); + IncludeSets.emit(writer, includes); writer.write(""); writer.write("using namespace Aws::$L::Model;", namespace); - protocolTraits.writeSerdeUsingDeclarations(writer); + writer.write("using namespace Aws::Utils::Stream;"); + writer.write("using namespace Aws::Utils;"); writer.write("using namespace Aws;"); writer.write(""); - protocolTraits.writeResultSerdeImpls(writer, className); + writer.write("$L::$L(Aws::AmazonWebServiceResult&& result) { *this = std::move(result); }", + className, className); + writer.write(""); + writer.openBlock("$L& $L::operator=(Aws::AmazonWebServiceResult&& result) {", "}", + className, className, () -> { + writer.write("m_HttpResponseCode = result.GetResponseCode();"); + writer.write("$L = result.TakeOwnershipOfPayload();", streamField); + writer.write("$LHasBeenSet = true;", streamField); + writer.write("// TODO: header-bound member deserialization"); + protocolTraits.writeResultStatusCodeMembers(writer, shape, model); + writer.write("return *this;"); + }); writer.write(""); }); } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/SubObjectRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/SubObjectRenderer.java index ab4917422869..571d7d1f4228 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/SubObjectRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/SubObjectRenderer.java @@ -8,16 +8,15 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; import com.amazonaws.util.awsclientsmithygenerator.generators.model.CppTypeMapper; import com.amazonaws.util.awsclientsmithygenerator.generators.model.MemberRenderer; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.FileKind; import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.ProtocolTraits; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeRenderer; import software.amazon.smithy.model.Model; import software.amazon.smithy.model.shapes.ServiceShape; import software.amazon.smithy.model.shapes.Shape; -import software.amazon.smithy.model.shapes.StructureShape; +import software.amazon.smithy.model.traits.StreamingTrait; import java.util.List; -import java.util.Set; -import java.util.TreeSet; /** * Renders C++ headers and sources for sub-object (intermediate structure) shapes. @@ -49,28 +48,33 @@ public SubObjectRenderer(List subObjects, Model model, ServiceShape servi @Override public void render(CppWriterDelegator writerDelegator) { for (Shape shape : subObjects) { - if (shape.isStructureShape()) { - StructureShape struct = shape.asStructureShape().get(); - renderHeader(writerDelegator, struct); - renderSource(writerDelegator, struct); + // C2J models a union as a structure with "union": true and emits it through the same + // ModelClass templates, so structures and (non-streaming) unions render identically. + // @streaming unions are the event-stream shapes rendered by EventStreamRenderer / + // the outgoing-event-stream path; skip them here to avoid a double-write. + boolean isStruct = shape.isStructureShape(); + boolean isDataUnion = shape.isUnionShape() && !shape.hasTrait(StreamingTrait.class); + if (isStruct || isDataUnion) { + renderHeader(writerDelegator, shape); + renderSource(writerDelegator, shape); } } } - private void renderHeader(CppWriterDelegator writerDelegator, StructureShape shape) { - String className = shape.getId().getName(); + private void renderHeader(CppWriterDelegator writerDelegator, Shape shape) { + String className = CppTypeMapper.cppShapeName(shape); String fileName = "include/aws/" + smithyServiceName + "/model/" + className + ".h"; writerDelegator.useFileWriter(fileName, writer -> { writer.write("#pragma once"); // Includes - Set includes = new TreeSet<>(); - includes.add(""); - List memberIncludes = CppTypeMapper.getIncludesForShape(shape, model, smithyServiceName); - includes.addAll(memberIncludes); - for (String include : includes) { - writer.write("#include $L", include); + List includes = new java.util.ArrayList<>(); + includes.add("aws/" + smithyServiceName + "/" + namespace + "_EXPORTS.h"); + for (String memberInc : CppTypeMapper.getIncludesForShape(shape, model, smithyServiceName)) { + includes.add(memberInc.replaceAll("^<|>$", "")); } + includes.addAll(protocolTraits.serdeIncludes(FileKind.SUBOBJECT_HEADER)); + IncludeSets.emit(writer, includes); boolean allPrimitive = shape.getAllMembers().values().stream() .map(m -> model.expectShape(m.getTarget())) @@ -92,12 +96,18 @@ private void renderHeader(CppWriterDelegator writerDelegator, StructureShape sha writer.openBlock("class $L {", "};", className, () -> { writer.write("public:"); protocolTraits.writeSerdeMethodDecls(writer, exportMacro, className, null); - writer.write(""); - MemberRenderer.renderPublicSection(writer, shape, model, exportMacro, className); - writer.dedent(); - writer.write("private:"); - writer.indent(); - MemberRenderer.renderPrivateSection(writer, shape, model); + // A memberless shape ends right after its serde decls: C2J emits no accessors + // and no private: section (ModelClassMembersAndInlines.vm gates both on + // $shape.members.size() > 0). + if (!shape.getAllMembers().isEmpty()) { + boolean wideIntegers = protocolTraits.widensIntegers(); + writer.write(""); + MemberRenderer.renderPublicSection(writer, shape, model, exportMacro, className, wideIntegers); + writer.dedent(); + writer.write("private:"); + writer.indent(); + MemberRenderer.renderPrivateSection(writer, shape, model, wideIntegers); + } }); writer.write(""); @@ -107,18 +117,21 @@ private void renderHeader(CppWriterDelegator writerDelegator, StructureShape sha }); } - private void renderSource(CppWriterDelegator writerDelegator, StructureShape shape) { - String className = shape.getId().getName(); + private void renderSource(CppWriterDelegator writerDelegator, Shape shape) { + String className = CppTypeMapper.cppShapeName(shape); String fileName = "source/model/" + className + ".cpp"; writerDelegator.useFileWriter(fileName, writer -> { - protocolTraits.writeSerdeInclude(writer); - writer.write("#include ", smithyServiceName, className); - writer.write(""); - writer.write("#include "); + List includes = new java.util.ArrayList<>( + IncludeSets.subObjectSourceBase(smithyServiceName, className)); + includes.addAll(protocolTraits.serdeIncludes(FileKind.SUBOBJECT_SOURCE)); + // Serde-implementation includes derived from members (e.g. HashingUtils.h for blob + // Base64 serde), matching C2J's computeSourceIncludes. + includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, model, smithyServiceName)); + IncludeSets.emit(writer, includes); writer.write(""); - protocolTraits.writeSerdeUsingDeclarations(writer); + IncludeSets.emitUsings(writer, protocolTraits.serdeUsings(FileKind.SUBOBJECT_SOURCE)); writer.write(""); writer.writeNamespaceOpen("Aws"); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/transforms/GlobalTransforms.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/transforms/GlobalTransforms.java index 122946d678ee..fc11b5373dd7 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/transforms/GlobalTransforms.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/transforms/GlobalTransforms.java @@ -5,6 +5,8 @@ package com.amazonaws.util.awsclientsmithygenerator.generators.model.transforms; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ModelTransform; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; import software.amazon.smithy.model.Model; import software.amazon.smithy.model.knowledge.TopDownIndex; import software.amazon.smithy.model.shapes.ListShape; @@ -14,10 +16,14 @@ 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.StructureShape; +import software.amazon.smithy.model.traits.RequiredTrait; import java.util.ArrayDeque; +import java.util.ArrayList; import java.util.Deque; import java.util.HashSet; +import java.util.List; import java.util.Optional; import java.util.Set; @@ -89,9 +95,12 @@ public static Set computeReachableShapes(Model model, ServiceShape serv TopDownIndex index = TopDownIndex.of(model); Deque queue = new ArrayDeque<>(); - // Seed queue with all operation input/output/error shapes + // Seed queue with all operation input/output/error shapes. Use getInputShape() + // so no-input operations (input target smithy.api#Unit) stay reachable, keeping + // the classifier and reachability set in agreement. The BFS below null-guards via + // model.getShape(id).ifPresent(...), so a possibly-absent Unit id is safe to add. for (OperationShape op : index.getContainedOperations(service)) { - op.getInput().ifPresent(queue::add); + queue.add(op.getInputShape()); op.getOutput().ifPresent(queue::add); op.getErrors().forEach(queue::add); } @@ -119,13 +128,70 @@ public static Set computeReachableShapes(Model model, ServiceShape serv } /** - * Returns this class as a no-op ModelTransform. + * Returns this class as a ModelTransform. * - *

    GlobalTransforms currently operates at classification time (via computeReachableShapes), - * not at model-transform time. This factory exists to reserve a slot in the pipeline - * for future pre-generation model mutations (shape renaming, injection, etc.). + *

    Currently the only pre-generation model mutation is {@link #injectResponseMetadata}. */ public static ModelTransform asTransform() { - return (model, service) -> model; + return GlobalTransforms::injectResponseMetadata; + } + + /** + * For awsQuery / ec2Query services, injects a {@code ResponseMetadata} structure (carrying + * a {@code RequestId} string member) and adds it as a {@code @required} member on every + * result (operation output) shape. This mirrors the legacy C2J + * {@code QueryCppClientGenerator.addRequestIdToResults} injection, so that Query/EC2 result + * classes expose {@code GetResponseMetadata()} and back the {@code m_responseMetadata} + * deserialization emitted by {@code QueryXmlProtocolTraits}. Other protocols are unchanged. + * + * @param model the current model + * @param service the service being generated + * @return the model with ResponseMetadata injected, or the input model for non-query protocols + */ + public static Model injectResponseMetadata(Model model, ServiceShape service) { + Protocol protocol = ProtocolResolver.resolve(service, model); + if (protocol != Protocol.QUERY_XML && protocol != Protocol.EC2) { + return model; + } + + String namespace = service.getId().getNamespace(); + ShapeId responseMetadataId = ShapeId.fromParts(namespace, "ResponseMetadata"); + + // ResponseMetadata { RequestId: String } + StructureShape responseMetadata = StructureShape.builder() + .id(responseMetadataId) + .addMember(MemberShape.builder() + .id(responseMetadataId.withMember("RequestId")) + .target("smithy.api#String") + .build()) + .build(); + + // The @required ResponseMetadata member added to each result shape. + List replacements = new ArrayList<>(); + replacements.add(responseMetadata); + + TopDownIndex index = TopDownIndex.of(model); + Set outputIds = new HashSet<>(); + for (OperationShape op : index.getContainedOperations(service)) { + op.getOutput().ifPresent(outputIds::add); + } + + for (ShapeId outputId : outputIds) { + model.getShape(outputId).flatMap(Shape::asStructureShape).ifPresent(result -> { + if (result.getMember("ResponseMetadata").isPresent()) { + return; + } + StructureShape withMetadata = result.toBuilder() + .addMember(MemberShape.builder() + .id(result.getId().withMember("ResponseMetadata")) + .target(responseMetadataId) + .addTrait(new RequiredTrait()) + .build()) + .build(); + replacements.add(withMetadata); + }); + } + + return model.toBuilder().addShapes(replacements).build(); } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapperTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapperTest.java index ff8743208996..5784227730d6 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapperTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapperTest.java @@ -41,6 +41,23 @@ void integerShape_mapsToInt() { assertEquals("int", CppTypeMapper.getCppType(shape, model)); } + @Test + void integerShape_wideIntegers_mapsToInt64() { + // C2J's CBOR type mapping widens integer -> int64_t (CORAL_TYPE_TO_CBOR_CPP_TYPE_MAPPING), + // used in CBOR sub-object and result headers ($protocol == smithy-rpc-v2-cbor). + IntegerShape shape = IntegerShape.builder().id("com.example#Foo").build(); + Model model = Model.builder().addShape(shape).build(); + assertEquals("int64_t", CppTypeMapper.getCppType(shape, model, true)); + } + + @Test + void longShape_wideIntegers_staysLongLong() { + // Only integer widens under CBOR; long is long long in every mapping. + LongShape shape = LongShape.builder().id("com.example#Foo").build(); + Model model = Model.builder().addShape(shape).build(); + assertEquals("long long", CppTypeMapper.getCppType(shape, model, true)); + } + @Test void longShape_mapsToLongLong() { LongShape shape = LongShape.builder().id("com.example#Foo").build(); @@ -76,6 +93,17 @@ void blobShape_mapsToAwsByteBuffer() { assertEquals("Aws::Utils::ByteBuffer", CppTypeMapper.getCppType(shape, model)); } + @Test + void sensitiveBlobShape_mapsToCryptoBuffer() { + // C2J maps a @sensitive blob to CryptoBuffer (the "sensitive_blob" type-mapping key in + // CppViewHelper), while a plain blob stays ByteBuffer. + BlobShape shape = BlobShape.builder().id("com.example#Foo") + .addTrait(new software.amazon.smithy.model.traits.SensitiveTrait()) + .build(); + Model model = Model.builder().addShape(shape).build(); + assertEquals("Aws::Utils::CryptoBuffer", CppTypeMapper.getCppType(shape, model)); + } + @Test void timestampShape_mapsToAwsDateTime() { TimestampShape shape = TimestampShape.builder().id("com.example#Foo").build(); @@ -124,6 +152,27 @@ void unionShape_mapsToShapeName() { assertEquals("MyUnion", CppTypeMapper.getCppType(union, model)); } + @Test + void enumShape_lowerCamelName_mapsToUpperCamelType() { + // IAM-style lowerCamel enum shape names must map to UpperCamel C++ types, matching C2J. + software.amazon.smithy.model.shapes.EnumShape en = software.amazon.smithy.model.shapes.EnumShape.builder() + .id("com.example#statusType").addMember("Active", "Active").build(); + Model model = Model.builder().addShape(en).build(); + assertEquals("StatusType", CppTypeMapper.getCppType(en, model)); + assertEquals(java.util.Optional.of("StatusType::NOT_SET"), CppTypeMapper.getDefaultValue(en)); + assertEquals(java.util.Optional.of(""), + CppTypeMapper.getIncludeForMemberType(en, model, "iam")); + } + + @Test + void structureShape_lowerCamelName_mapsToUpperCamelType() { + StructureShape struct = StructureShape.builder().id("com.example#nestedThing").build(); + Model model = Model.builder().addShape(struct).build(); + assertEquals("NestedThing", CppTypeMapper.getCppType(struct, model)); + assertEquals(java.util.Optional.of(""), + CppTypeMapper.getIncludeForMemberType(struct, model, "iam")); + } + @Test void documentShape_mapsToAwsDocument() { DocumentShape shape = DocumentShape.builder().id("com.example#Foo").build(); @@ -323,6 +372,40 @@ void getIncludesForShape_withListMember_includesVectorAndElement() { assertTrue(includes.contains("")); } + @Test + void getIncludesForShape_withIdempotencyTokenMember_includesUuidHeader() { + // C2J adds to any shape carrying an @idempotencyToken member, + // because such members are brace-initialized with Aws::Utils::UUID::PseudoRandomUUID() + // (CppViewHelper.java). The include must be present for the initializer to compile. + StringShape str = StringShape.builder().id("com.example#Str").build(); + StructureShape struct = StructureShape.builder() + .id("com.example#MyRequest") + .addMember(MemberShape.builder() + .id("com.example#MyRequest$clientToken").target("com.example#Str") + .addTrait(new software.amazon.smithy.model.traits.IdempotencyTokenTrait()) + .build()) + .build(); + Model model = Model.builder().addShapes(str, struct).build(); + + List includes = CppTypeMapper.getIncludesForShape(struct, model, "myservice"); + assertTrue(includes.contains(""), + "Shape with idempotency-token member should include UUID.h: " + includes); + } + + @Test + void getIncludesForShape_withoutIdempotencyToken_noUuidHeader() { + StringShape str = StringShape.builder().id("com.example#Str").build(); + StructureShape struct = StructureShape.builder() + .id("com.example#MyRequest") + .addMember("name", str.getId()) + .build(); + Model model = Model.builder().addShapes(str, struct).build(); + + List includes = CppTypeMapper.getIncludesForShape(struct, model, "myservice"); + assertFalse(includes.contains(""), + "Shape without idempotency-token member should not include UUID.h: " + includes); + } + @Test void getIncludesForShape_withMapMember_includesMapKeyAndValue() { StringShape str = StringShape.builder().id("com.example#Str").build(); @@ -343,4 +426,45 @@ void getIncludesForShape_withMapMember_includesMapKeyAndValue() { assertTrue(includes.contains("")); assertTrue(includes.contains("")); } + + // --- getSourceIncludesForShape tests (serde-implementation includes) --- + + @Test + void getSourceIncludesForShape_withBlobMember_includesHashingUtils() { + // C2J adds HashingUtils.h to the SOURCE of any shape with a blob member (or list/map of + // blobs) because blob serde uses Base64Encode/Decode (CppViewHelper.computeSourceIncludes). + BlobShape blob = BlobShape.builder().id("com.example#Body").build(); + StructureShape struct = StructureShape.builder() + .id("com.example#AudioSource").addMember("bytes", blob.getId()).build(); + Model model = Model.builder().addShapes(blob, struct).build(); + + List inc = CppTypeMapper.getSourceIncludesForShape(struct, model, "myservice"); + assertTrue(inc.contains("aws/core/utils/HashingUtils.h"), inc.toString()); + } + + @Test + void getSourceIncludesForShape_withListOfBlobs_includesHashingUtils() { + BlobShape blob = BlobShape.builder().id("com.example#Body").build(); + ListShape list = ListShape.builder() + .id("com.example#BodyList") + .member(MemberShape.builder().id("com.example#BodyList$member").target("com.example#Body").build()) + .build(); + StructureShape struct = StructureShape.builder() + .id("com.example#MyShape").addMember("chunks", list.getId()).build(); + Model model = Model.builder().addShapes(blob, list, struct).build(); + + List inc = CppTypeMapper.getSourceIncludesForShape(struct, model, "myservice"); + assertTrue(inc.contains("aws/core/utils/HashingUtils.h"), inc.toString()); + } + + @Test + void getSourceIncludesForShape_withoutBlob_noHashingUtils() { + StringShape str = StringShape.builder().id("com.example#Str").build(); + StructureShape struct = StructureShape.builder() + .id("com.example#MyShape").addMember("name", str.getId()).build(); + Model model = Model.builder().addShapes(str, struct).build(); + + List inc = CppTypeMapper.getSourceIncludesForShape(struct, model, "myservice"); + assertFalse(inc.contains("aws/core/utils/HashingUtils.h"), inc.toString()); + } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/EnumRendererTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/EnumRendererTest.java index 806c523a5d13..35dd58fd79a5 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/EnumRendererTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/EnumRendererTest.java @@ -41,6 +41,41 @@ void renderHeader_producesEnumClass() { "Missing GetNameFor declaration: " + output); } + @Test + void renderHeader_capitalizesLowerCamelEnumName() { + // Some Smithy models (e.g. IAM) name enum shapes in lowerCamel. C2J normalizes every + // shape name to UpperCamel, so the C++ enum type, mapper namespace, and mapper + // functions must be capitalized regardless of the model's casing. + EnumShape enumShape = EnumShape.builder() + .id("com.example#statusType") + .addMember("Active", "Active") + .addMember("Inactive", "Inactive") + .build(); + CppWriter writer = new CppWriter(); + EnumRenderer.renderHeader(writer, enumShape, "IAM", "AWS_IAM_API", "iam"); + String output = writer.toString(); + assertTrue(output.contains("enum class StatusType {"), "Enum type must be UpperCamel: " + output); + assertTrue(output.contains("namespace StatusTypeMapper {"), "Mapper namespace must be UpperCamel: " + output); + assertTrue(output.contains("GetStatusTypeForName"), "Mapper fn must be UpperCamel: " + output); + assertTrue(output.contains("GetNameForStatusType"), "Mapper fn must be UpperCamel: " + output); + assertFalse(output.contains("statusType"), "Must not emit lowerCamel enum name: " + output); + } + + @Test + void renderSource_capitalizesLowerCamelEnumName() { + EnumShape enumShape = EnumShape.builder() + .id("com.example#statusType") + .addMember("Active", "Active") + .build(); + CppWriter writer = new CppWriter(); + EnumRenderer.renderSource(writer, enumShape, "IAM", "AWS_IAM_API", "iam"); + String output = writer.toString(); + assertTrue(output.contains("#include "), "Include must be UpperCamel: " + output); + assertTrue(output.contains("namespace StatusTypeMapper {"), "Mapper namespace must be UpperCamel: " + output); + assertTrue(output.contains("StatusType GetStatusTypeForName"), "Mapper fn must be UpperCamel: " + output); + assertFalse(output.contains("statusType"), "Must not emit lowerCamel enum name: " + output); + } + @Test void renderHeader_includesExportsHeader() { EnumShape enumShape = EnumShape.builder() diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/EventStreamRendererTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/EventStreamRendererTest.java index 07423bc434ae..ac4ba86ffc0f 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/EventStreamRendererTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/EventStreamRendererTest.java @@ -34,11 +34,19 @@ private static Model twoEventModel() { .id("com.example#BetaEvent") .addMember("data", str.getId()) .build(); + // Non-modeled exception: only a trivial "message" member -> generic ExampleError. StructureShape exc = StructureShape.builder() .id("com.example#BadException") .addTrait(new ErrorTrait("client")) .addMember("message", str.getId()) .build(); + // Modeled exception: has a non-trivial member -> concrete type + model include. + StructureShape modeledExc = StructureShape.builder() + .id("com.example#DetailedException") + .addTrait(new ErrorTrait("client")) + .addMember("message", str.getId()) + .addMember("detail", str.getId()) + .build(); UnionShape stream = UnionShape.builder() .id("com.example#MyStreamEventStream") .addTrait(new StreamingTrait()) @@ -47,14 +55,22 @@ private static Model twoEventModel() { b -> b.addTrait(new DocumentationTrait("

    Alpha event doc.

    "))) .addMember("beta", eventB.getId()) .addMember("badException", exc.getId()) + .addMember("detailedException", modeledExc.getId()) .build(); StructureShape input = StructureShape.builder() .id("com.example#DoStreamInput") .addMember("name", str.getId()) .build(); + // Output carries the streaming union member AND a non-streaming member: C2J synthesizes + // the InitialResponse from the result's non-event-stream members. StructureShape output = StructureShape.builder() .id("com.example#DoStreamOutput") - .addMember("stream", stream.getId()) + .addMember(software.amazon.smithy.model.shapes.MemberShape.builder() + .id("com.example#DoStreamOutput$stream").target(stream.getId()) + .addTrait(new software.amazon.smithy.model.traits.HttpPayloadTrait()).build()) + .addMember(software.amazon.smithy.model.shapes.MemberShape.builder() + .id("com.example#DoStreamOutput$contentType").target(str.getId()) + .addTrait(new software.amazon.smithy.model.traits.HttpHeaderTrait("X-Content-Type")).build()) .build(); software.amazon.smithy.model.shapes.OperationShape op = software.amazon.smithy.model.shapes.OperationShape.builder() @@ -67,7 +83,7 @@ private static Model twoEventModel() { .version("2024-01-01") .addOperation(op.getId()) .build(); - return Model.builder().addShapes(str, stream, eventA, eventB, exc, input, output, op, service).build(); + return Model.builder().addShapes(str, stream, eventA, eventB, exc, modeledExc, input, output, op, service).build(); } private static String render(String fileSuffix) { @@ -132,6 +148,34 @@ void eventStreamUnionHeader_typesEventAndExceptionMembers() { assertTrue(h.contains("ExampleError"), "Exception members must be typed as ExampleError: " + h); } + @Test + void eventStreamUnionHeader_modeledExceptionUsesConcreteTypeAndInclude() { + // C2J types a modeled exception member (extra members beyond message/code) as its concrete + // shape and includes its model header, while a non-modeled exception stays the generic + // Error (no include). Matches CppViewHelper's isException/isModeledException gate. + String h = render("MyStreamEventStream.h"); + // Modeled exception -> concrete type + include. + assertTrue(h.contains("const DetailedException& GetDetailedException()"), + "Modeled exception must use its concrete type: " + h); + assertTrue(h.contains("#include "), + "Modeled exception must bring its model include: " + h); + // Non-modeled exception -> generic ExampleError. + assertTrue(h.contains("const ExampleError& GetBadException()"), + "Non-modeled exception must use the generic error type: " + h); + } + + @Test + void eventStreamUnionHeader_omitsServiceErrorsInclude() { + // C2J's computeHeaderIncludes skips the model include for non-modeled exception members + // (CppViewHelper: `if (next.isException() && !next.isModeledException()) continue;`). + // The union's exception members are the generic ExampleError wrapper, so the union header + // must NOT include the service Errors header — it resolves transitively. The handler + // header (a separate file) still includes it. + String h = render("MyStreamEventStream.h"); + assertFalse(h.contains("#include "), + "Union header must not include the service Errors header: " + h); + } + @Test void eventStreamUnionHeader_rendersClassAndMemberDocs() { String h = render("MyStreamEventStream.h"); @@ -158,11 +202,69 @@ void initialResponseHeader_hasHeaderCollectionCtorAndSerdeDecls() { "HeaderValueCollection ctor must come before Jsonize: " + h); } + @Test + void initialResponseHeader_rendersNonStreamingResultMembers() { + // C2J synthesizes InitialResponse from the result's non-event-stream members, so the + // header must carry accessors for those members (here: contentType) plus a private section. + // The @httpPayload streaming union member (stream) must NOT appear. + String h = render("DoStreamInitialResponse.h"); + assertTrue(h.contains("GetContentType") && h.contains("SetContentType") && h.contains("WithContentType"), + "InitialResponse must render accessors for non-streaming result members: " + h); + assertTrue(h.contains("bool m_contentTypeHasBeenSet = false;"), + "InitialResponse must render private members: " + h); + assertFalse(h.contains("GetStream"), + "InitialResponse must not render the streaming union member: " + h); + } + @Test void initialResponseSource_hasHeaderCtorDefinition() { String c = render("DoStreamInitialResponse.cpp"); assertTrue(c.contains("DoStreamInitialResponse::DoStreamInitialResponse(const Http::HeaderValueCollection&"), "Missing header ctor definition: " + c); + // The header ctor must delegate to the default ctor so members are value-initialized + // before the header-derived ones are set (matches C2J). + assertTrue(c.contains( + "DoStreamInitialResponse::DoStreamInitialResponse(const Http::HeaderValueCollection& " + + "responseHeaders) : DoStreamInitialResponse() {"), + "Header ctor must delegate to the default ctor: " + c); + } + + @Test + void initialResponseSource_hasJsonSerdeIncludesAndUsings() { + // The JSON InitialResponse source matches C2J: StringUtils + UnreferencedParam + the JSON + // serializer, the Json/Utils usings, and . + String c = render("DoStreamInitialResponse.cpp"); + assertTrue(c.contains("#include "), c); + assertTrue(c.contains("#include "), c); + assertTrue(c.contains("#include "), c); + assertTrue(c.contains("#include "), c); + assertTrue(c.contains("using namespace Aws::Utils::Json;"), c); + assertTrue(c.contains("using namespace Aws::Utils;"), c); + // The header-bound member (contentType) pulls AWSStringStream.h into the source, matching + // C2J's computeSourceIncludes. + assertTrue(c.contains("#include "), c); + } + + @Test + void initialResponseSource_wrapsBodyInNamespaceBlockNotUsingModel() { + // C2J renders InitialResponse via the sub-object source template, which wraps the body in + // an explicit namespace block rather than a `using namespace ...Model;`. + String c = render("DoStreamInitialResponse.cpp"); + assertTrue(c.contains("namespace Aws"), c); + assertTrue(c.contains("namespace Example"), c); + assertTrue(c.contains("namespace Model"), c); + assertTrue(c.contains("// namespace Model"), c); + assertFalse(c.contains("using namespace Aws::Example::Model;"), + "InitialResponse must use a namespace block, not using-Model: " + c); + } + + @Test + void handlerSource_hasProtocolSerdeIncludeAndUsing() { + // The JSON handler parses event/exception payloads as JSON, so its source includes the + // JSON serializer and uses the Json namespace, matching C2J JsonEventStreamHandlerSource.vm. + String c = render("DoStreamHandler.cpp"); + assertTrue(c.contains("#include "), c); + assertTrue(c.contains("using namespace Aws::Utils::Json;"), c); } @Test diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/GlobalTransformsTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/GlobalTransformsTest.java index 9f584a26dbb1..fd2fc0609510 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/GlobalTransformsTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/GlobalTransformsTest.java @@ -373,4 +373,76 @@ void computeReachableShapes_errorShapes_areReachable() { assertTrue(reachable.contains(ShapeId.from("com.example#MyError"))); } + + // --- injectResponseMetadata tests --- + + /** A single-operation service under the given protocol trait, output has one plain member. */ + private static Model oneOutputModel(software.amazon.smithy.model.traits.Trait protocolTrait) { + StructureShape input = StructureShape.builder().id("com.example#DoThingInput").build(); + StructureShape output = StructureShape.builder() + .id("com.example#DoThingOutput") + .addMember(MemberShape.builder() + .id("com.example#DoThingOutput$name").target("smithy.api#String").build()) + .build(); + OperationShape op = OperationShape.builder() + .id("com.example#DoThing").input(input.getId()).output(output.getId()).build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#Example").version("2024-01-01") + .addTrait(protocolTrait).addOperation(op.getId()).build(); + return Model.assembler().addShapes(input, output, op, service).assemble().unwrap(); + } + + private static ServiceShape serviceOf(Model model) { + return model.expectShape(ShapeId.from("com.example#Example"), ServiceShape.class); + } + + @Test + void injectResponseMetadata_awsQuery_addsResponseMetadataMemberToResult() { + Model model = oneOutputModel(new software.amazon.smithy.aws.traits.protocols.AwsQueryTrait()); + Model out = GlobalTransforms.asTransform().apply(model, serviceOf(model)); + + StructureShape result = out.expectShape( + ShapeId.from("com.example#DoThingOutput"), StructureShape.class); + assertTrue(result.getMember("ResponseMetadata").isPresent(), + "Query result should carry an injected ResponseMetadata member"); + MemberShape rm = result.getMember("ResponseMetadata").get(); + assertTrue(rm.hasTrait(software.amazon.smithy.model.traits.RequiredTrait.class), + "ResponseMetadata member should be @required, matching C2J"); + } + + @Test + void injectResponseMetadata_awsQuery_addsResponseMetadataStructureWithRequestId() { + Model model = oneOutputModel(new software.amazon.smithy.aws.traits.protocols.AwsQueryTrait()); + Model out = GlobalTransforms.asTransform().apply(model, serviceOf(model)); + + ShapeId rmId = out.expectShape(ShapeId.from("com.example#DoThingOutput"), StructureShape.class) + .getMember("ResponseMetadata").get().getTarget(); + StructureShape rm = out.expectShape(rmId, StructureShape.class); + assertEquals("ResponseMetadata", rmId.getName()); + assertTrue(rm.getMember("RequestId").isPresent(), + "ResponseMetadata should have a RequestId member"); + } + + @Test + void injectResponseMetadata_ec2_addsResponseMetadataMemberToResult() { + Model model = oneOutputModel(new software.amazon.smithy.aws.traits.protocols.Ec2QueryTrait()); + Model out = GlobalTransforms.asTransform().apply(model, serviceOf(model)); + + StructureShape result = out.expectShape( + ShapeId.from("com.example#DoThingOutput"), StructureShape.class); + assertTrue(result.getMember("ResponseMetadata").isPresent(), + "EC2 result should carry an injected ResponseMetadata member"); + } + + @Test + void injectResponseMetadata_restJson_leavesResultUnchanged() { + Model model = oneOutputModel( + software.amazon.smithy.aws.traits.protocols.RestJson1Trait.builder().build()); + Model out = GlobalTransforms.asTransform().apply(model, serviceOf(model)); + + StructureShape result = out.expectShape( + ShapeId.from("com.example#DoThingOutput"), StructureShape.class); + assertFalse(result.getMember("ResponseMetadata").isPresent(), + "Non-query protocols must not get ResponseMetadata injected"); + } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererTest.java index 1b5b2fc992cb..0079791158a7 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererTest.java @@ -10,6 +10,7 @@ import software.amazon.smithy.model.shapes.BooleanShape; import software.amazon.smithy.model.shapes.IntegerShape; import software.amazon.smithy.model.shapes.ListShape; +import software.amazon.smithy.model.shapes.MapShape; import software.amazon.smithy.model.shapes.MemberShape; import software.amazon.smithy.model.shapes.StringShape; import software.amazon.smithy.model.shapes.StructureShape; @@ -35,6 +36,30 @@ void renderPublicSection_stringMember_producesGetSetWith() { assertTrue(output.contains("MyShape& WithName(NameT&& value)"), "Missing With: " + output); } + @Test + void renderPublicSection_lowercaseMember_capitalizesMethodNames() { + // Smithy member names frequently start lowercase (e.g. "extendedKeyUsage"). + // The legacy C2J convention capitalizes the accessor method names and template + // params while keeping the decapitalized field name (m_extendedKeyUsage). + StringShape str = StringShape.builder().id("com.example#String").build(); + StructureShape shape = StructureShape.builder() + .id("com.example#MyShape") + .addMember("extendedKeyUsage", str.getId()) + .build(); + Model model = Model.builder().addShapes(str, shape).build(); + CppWriter writer = new CppWriter(); + MemberRenderer.renderPublicSection(writer, shape, model, "AWS_TEST_API", "MyShape"); + String output = writer.toString(); + assertTrue(output.contains("GetExtendedKeyUsage() const"), "Getter should be capitalized: " + output); + assertTrue(output.contains("ExtendedKeyUsageHasBeenSet() const"), "HasBeenSet should be capitalized: " + output); + assertTrue(output.contains("SetExtendedKeyUsage(ExtendedKeyUsageT&& value)"), "Setter should be capitalized: " + output); + assertTrue(output.contains("WithExtendedKeyUsage(ExtendedKeyUsageT&& value)"), "With should be capitalized: " + output); + assertTrue(output.contains("m_extendedKeyUsage = std::forward"), "Field should stay decapitalized: " + output); + // Must not emit the raw lowercase-first method names. + assertFalse(output.contains("GetextendedKeyUsage"), "Must not emit lowercase getter: " + output); + assertFalse(output.contains("WithextendedKeyUsage"), "Must not emit lowercase With: " + output); + } + @Test void renderPublicSection_listMember_producesAddMethod() { StringShape str = StringShape.builder().id("com.example#String").build(); @@ -74,6 +99,147 @@ void renderPublicSection_listMember_addTemplateDefaultIsElementType() { "Add template default should be element type: " + output); } + @Test + void renderPublicSection_listOfPrimitive_addIsByValue() { + // C2J emits by-value Add for lists of primitive OR enum elements; only non-primitive, + // non-enum elements get the templated forwarding Add. + IntegerShape intShape = IntegerShape.builder().id("com.example#Integer").build(); + ListShape list = ListShape.builder() + .id("com.example#IntList") + .member(MemberShape.builder().id("com.example#IntList$member").target("com.example#Integer").build()) + .build(); + StructureShape shape = StructureShape.builder() + .id("com.example#MyShape") + .addMember("Counts", list.getId()) + .build(); + Model model = Model.builder().addShapes(intShape, list, shape).build(); + CppWriter writer = new CppWriter(); + MemberRenderer.renderPublicSection(writer, shape, model, "AWS_TEST_API", "MyShape"); + String output = writer.toString(); + assertTrue(output.contains("inline MyShape& AddCounts(int value)"), + "List of primitive should get by-value Add: " + output); + assertTrue(output.contains("m_counts.push_back(value)"), + "By-value list Add should push_back directly: " + output); + assertFalse(output.contains("AddCounts(CountsT&&"), + "Must not emit templated Add for primitive element: " + output); + } + + @Test + void renderPublicSection_mapWithPrimitiveValue_addIsByValue() { + // C2J emits a by-value Add for maps unless BOTH key and value are non-primitive + // AND non-enum. Here value is int (primitive), so Add must be a plain by-value overload. + StringShape str = StringShape.builder().id("com.example#String").build(); + IntegerShape intShape = IntegerShape.builder().id("com.example#Integer").build(); + MapShape map = MapShape.builder() + .id("com.example#SummaryMap") + .key(MemberShape.builder().id("com.example#SummaryMap$key").target("com.example#String").build()) + .value(MemberShape.builder().id("com.example#SummaryMap$value").target("com.example#Integer").build()) + .build(); + StructureShape shape = StructureShape.builder() + .id("com.example#MyShape") + .addMember("SummaryMap", map.getId()) + .build(); + Model model = Model.builder().addShapes(str, intShape, map, shape).build(); + CppWriter writer = new CppWriter(); + MemberRenderer.renderPublicSection(writer, shape, model, "AWS_TEST_API", "MyShape"); + String output = writer.toString(); + assertTrue(output.contains("MyShape& AddSummaryMap(Aws::String key, int value)"), + "Map with primitive value should get by-value Add: " + output); + assertTrue(output.contains("m_summaryMap.emplace(key, value)"), + "By-value Add should emplace directly: " + output); + assertFalse(output.contains("AddSummaryMap(SummaryMapKeyT&&"), + "Must not emit templated forwarding Add when value is primitive: " + output); + } + + @Test + void renderPublicSection_mapWithNonPrimitiveKeyAndValue_addIsTemplated() { + // Both key (String) and value (struct) are non-primitive/non-enum -> templated Add. + StringShape str = StringShape.builder().id("com.example#String").build(); + StructureShape valueStruct = StructureShape.builder().id("com.example#ValueStruct").build(); + MapShape map = MapShape.builder() + .id("com.example#ThingMap") + .key(MemberShape.builder().id("com.example#ThingMap$key").target("com.example#String").build()) + .value(MemberShape.builder().id("com.example#ThingMap$value").target("com.example#ValueStruct").build()) + .build(); + StructureShape shape = StructureShape.builder() + .id("com.example#MyShape") + .addMember("ThingMap", map.getId()) + .build(); + Model model = Model.builder().addShapes(str, valueStruct, map, shape).build(); + CppWriter writer = new CppWriter(); + MemberRenderer.renderPublicSection(writer, shape, model, "AWS_TEST_API", "MyShape"); + String output = writer.toString(); + assertTrue(output.contains("MyShape& AddThingMap(ThingMapKeyT&& key, ThingMapValueT&& value)"), + "Map with non-primitive key/value should get templated Add: " + output); + assertTrue(output.contains("m_thingMap.emplace(std::forward(key), std::forward(value))"), + "Templated Add should perfect-forward: " + output); + } + + @Test + void renderPublicSection_documentMember_getterReturnsDocumentViewByValue() { + // C2J special-cases the document getter to return Aws::Utils::DocumentView by value + // (ModelClassMembersAndInlines.vm: $returnType = "Aws::Utils::DocumentView"), while the + // field and setter stay Aws::Utils::Document. + software.amazon.smithy.model.shapes.DocumentShape doc = + software.amazon.smithy.model.shapes.DocumentShape.builder().id("com.example#Doc").build(); + StructureShape shape = StructureShape.builder() + .id("com.example#MyShape") + .addMember("json", doc.getId()) + .build(); + Model model = Model.builder().addShapes(doc, shape).build(); + CppWriter writer = new CppWriter(); + MemberRenderer.renderPublicSection(writer, shape, model, "AWS_TEST_API", "MyShape"); + String output = writer.toString(); + assertTrue(output.contains("inline Aws::Utils::DocumentView GetJson() const { return m_json; }"), + "Document getter must return DocumentView by value: " + output); + assertFalse(output.contains("const Aws::Utils::Document& GetJson"), + "Document getter must not return const Document&: " + output); + // Setter still forwards an Aws::Utils::Document. + assertTrue(output.contains("template "), + "Document setter template default must be Aws::Utils::Document: " + output); + } + + @Test + void renderPublicSection_documentMember_privateFieldIsDocument() { + software.amazon.smithy.model.shapes.DocumentShape doc = + software.amazon.smithy.model.shapes.DocumentShape.builder().id("com.example#Doc").build(); + StructureShape shape = StructureShape.builder() + .id("com.example#MyShape") + .addMember("json", doc.getId()) + .build(); + Model model = Model.builder().addShapes(doc, shape).build(); + CppWriter writer = new CppWriter(); + MemberRenderer.renderPrivateSection(writer, shape, model); + String output = writer.toString(); + assertTrue(output.contains("Aws::Utils::Document m_json;"), + "Document field must be Aws::Utils::Document: " + output); + } + + @Test + void renderPublicSection_sensitiveBlobMember_usesCryptoBuffer() { + // A @sensitive blob member renders CryptoBuffer in the getter, setter template default, + // and (via renderPrivateSection) the field — matching C2J. + software.amazon.smithy.model.shapes.BlobShape sensitive = + software.amazon.smithy.model.shapes.BlobShape.builder().id("com.example#PartBody") + .addTrait(new software.amazon.smithy.model.traits.SensitiveTrait()).build(); + StructureShape shape = StructureShape.builder() + .id("com.example#MyShape") + .addMember("bytes", sensitive.getId()) + .build(); + Model model = Model.builder().addShapes(sensitive, shape).build(); + CppWriter pub = new CppWriter(); + MemberRenderer.renderPublicSection(pub, shape, model, "AWS_TEST_API", "MyShape"); + String pubOut = pub.toString(); + assertTrue(pubOut.contains("inline const Aws::Utils::CryptoBuffer& GetBytes() const"), + "Sensitive blob getter must be CryptoBuffer: " + pubOut); + assertTrue(pubOut.contains("template "), + "Sensitive blob setter template default must be CryptoBuffer: " + pubOut); + CppWriter priv = new CppWriter(); + MemberRenderer.renderPrivateSection(priv, shape, model); + assertTrue(priv.toString().contains("Aws::Utils::CryptoBuffer m_bytes{};"), + "Sensitive blob field must be CryptoBuffer: " + priv); + } + @Test void renderPublicSection_primitiveGetter_returnsByValue() { IntegerShape intShape = IntegerShape.builder().id("com.example#Integer").build(); @@ -140,6 +306,56 @@ void renderPrivateSection_nonPrimitiveMembers_noDefaultValue() { assertTrue(output.contains("bool m_nameHasBeenSet = false"), "Missing HasBeenSet flag: " + output); } + @Test + void renderPrivateSection_idempotencyTokenMember_initializesWithPseudoRandomUuidAndHasBeenSetTrue() { + // C2J auto-populates @idempotencyToken members with a random UUID at construction + // (ServiceClientModelHeaderMemberDeclaration.vm) and flags them as already-set + // (ModelClassMembersAndInlines.vm), so a caller who omits the token still gets + // idempotent behavior. The initializer and the =true flag must both be emitted. + StringShape str = StringShape.builder().id("com.example#String").build(); + StructureShape shape = StructureShape.builder() + .id("com.example#MyShape") + .addMember(MemberShape.builder() + .id("com.example#MyShape$clientToken").target("com.example#String") + .addTrait(new software.amazon.smithy.model.traits.IdempotencyTokenTrait()) + .build()) + .build(); + Model model = Model.builder().addShapes(str, shape).build(); + CppWriter writer = new CppWriter(); + MemberRenderer.renderPrivateSection(writer, shape, model); + String output = writer.toString(); + assertTrue(output.contains("Aws::String m_clientToken{Aws::Utils::UUID::PseudoRandomUUID()};"), + "Idempotency token should be initialized with PseudoRandomUUID: " + output); + assertTrue(output.contains("bool m_clientTokenHasBeenSet = true;"), + "Idempotency token HasBeenSet flag should default to true: " + output); + } + + @Test + void renderPrivateDataMembersExcluding_idempotencyTokenMember_initializesWithPseudoRandomUuid() { + // The streaming-result / event-stream path routes through the *Excluding overloads; + // they must apply the same idempotency-token initializer as the primary path. + StringShape str = StringShape.builder().id("com.example#String").build(); + StructureShape shape = StructureShape.builder() + .id("com.example#MyShape") + .addMember(MemberShape.builder() + .id("com.example#MyShape$clientToken").target("com.example#String") + .addTrait(new software.amazon.smithy.model.traits.IdempotencyTokenTrait()) + .build()) + .addMember("other", str.getId()) + .build(); + Model model = Model.builder().addShapes(str, shape).build(); + CppWriter writer = new CppWriter(); + MemberRenderer.renderPrivateDataMembersExcluding(writer, shape, model, "other"); + String dataOut = writer.toString(); + assertTrue(dataOut.contains("Aws::String m_clientToken{Aws::Utils::UUID::PseudoRandomUUID()};"), + "Excluding overload should also emit the idempotency-token initializer: " + dataOut); + CppWriter flagWriter = new CppWriter(); + MemberRenderer.renderPrivateHasBeenSetFlagsExcluding(flagWriter, shape, model, "other"); + String flagOut = flagWriter.toString(); + assertTrue(flagOut.contains("bool m_clientTokenHasBeenSet = true;"), + "Excluding overload should also emit HasBeenSet = true: " + flagOut); + } + @Test void renderPrivateSection_hasBeenSetFlagsGroupedAtEnd() { StringShape str = StringShape.builder().id("com.example#String").build(); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/OutgoingEventStreamRendererTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/OutgoingEventStreamRendererTest.java new file mode 100644 index 000000000000..f681d9b48550 --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/OutgoingEventStreamRendererTest.java @@ -0,0 +1,144 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model; + +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers.OutgoingEventStreamRenderer; +import org.junit.jupiter.api.Test; +import software.amazon.smithy.build.MockManifest; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.BlobShape; +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.ShapeId; +import software.amazon.smithy.model.shapes.StringShape; +import software.amazon.smithy.model.shapes.StructureShape; +import software.amazon.smithy.model.shapes.UnionShape; +import software.amazon.smithy.model.traits.EventPayloadTrait; +import software.amazon.smithy.model.traits.StreamingTrait; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class OutgoingEventStreamRendererTest { + + /** + * A bidirectional operation whose input binds a @streaming union with one event member whose + * payload is a nested structure (the implicit-structure case, like bedrock's + * BidirectionalInputPayloadPart). + */ + private static Model structurePayloadModel() { + StringShape str = StringShape.builder().id("com.example#String").build(); + BlobShape blob = BlobShape.builder().id("com.example#PartBody").build(); + // Event shape: single implicit blob member -> parent is the payload (structure encoding). + StructureShape event = StructureShape.builder() + .id("com.example#ChunkEvent") + .addMember("bytes", blob.getId()) + .build(); + UnionShape stream = UnionShape.builder() + .id("com.example#BidirectionalInput") + .addTrait(new StreamingTrait()) + .addMember("chunk", event.getId()) + .build(); + StructureShape input = StructureShape.builder() + .id("com.example#DoStreamInput") + .addMember(MemberShape.builder() + .id("com.example#DoStreamInput$body").target(stream.getId()) + .addTrait(new software.amazon.smithy.model.traits.HttpPayloadTrait()).build()) + .build(); + StructureShape output = StructureShape.builder() + .id("com.example#DoStreamOutput").addMember("r", str.getId()).build(); + OperationShape op = OperationShape.builder() + .id("com.example#DoStream").input(input.getId()).output(output.getId()).build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#Example").version("2024-01-01").addOperation(op.getId()).build(); + return Model.builder().addShapes(str, blob, event, stream, input, output, op, service).build(); + } + + /** Same shape but the single blob member is explicitly @eventPayload -> raw blob encoding. */ + private static Model blobPayloadModel() { + StringShape str = StringShape.builder().id("com.example#String").build(); + BlobShape blob = BlobShape.builder().id("com.example#PartBody").build(); + StructureShape event = StructureShape.builder() + .id("com.example#ChunkEvent") + .addMember(MemberShape.builder() + .id("com.example#ChunkEvent$bytes").target(blob.getId()) + .addTrait(new EventPayloadTrait()).build()) + .build(); + UnionShape stream = UnionShape.builder() + .id("com.example#BidirectionalInput") + .addTrait(new StreamingTrait()) + .addMember("chunk", event.getId()) + .build(); + StructureShape input = StructureShape.builder() + .id("com.example#DoStreamInput") + .addMember(MemberShape.builder() + .id("com.example#DoStreamInput$body").target(stream.getId()) + .addTrait(new software.amazon.smithy.model.traits.HttpPayloadTrait()).build()) + .build(); + StructureShape output = StructureShape.builder() + .id("com.example#DoStreamOutput").addMember("r", str.getId()).build(); + OperationShape op = OperationShape.builder() + .id("com.example#DoStream").input(input.getId()).output(output.getId()).build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#Example").version("2024-01-01").addOperation(op.getId()).build(); + return Model.builder().addShapes(str, blob, event, stream, input, output, op, service).build(); + } + + private static String render(Model model, Protocol protocol) { + ServiceShape service = model.expectShape(ShapeId.from("com.example#Example"), ServiceShape.class); + MockManifest manifest = new MockManifest(); + CppWriterDelegator delegator = new CppWriterDelegator(manifest); + List outgoing = + List.of(model.expectShape(ShapeId.from("com.example#BidirectionalInput"))); + new OutgoingEventStreamRenderer(outgoing, model, service, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example").render(delegator); + delegator.flushWriters(); + return manifest.getFileString(manifest.getFiles().stream() + .filter(p -> p.toString().endsWith("BidirectionalInput.h")).findFirst().orElseThrow()).orElseThrow(); + } + + @Test + void rendersEventEncoderStreamSubclassWithWriteMethod() { + String h = render(structurePayloadModel(), Protocol.JSON); + assertTrue(h.contains("class AWS_EXAMPLE_API BidirectionalInput : public Aws::Utils::Event::EventEncoderStream {"), h); + assertTrue(h.contains("BidirectionalInput() = default;"), h); + assertTrue(h.contains("explicit BidirectionalInput(std::shared_ptr streambuf)"), h); + assertTrue(h.contains("BidirectionalInput& WriteChunkEvent(const ChunkEvent& value) {"), h); + assertTrue(h.contains("msg.InsertEventHeader(\":event-type\", Aws::String(\"chunk\"));"), h); + assertTrue(h.contains("WriteEvent(msg);"), h); + assertTrue(h.contains("#include "), h); + assertTrue(h.contains("#include "), h); + } + + @Test + void jsonStructurePayload_usesJsonizeAndApplicationJson() { + String h = render(structurePayloadModel(), Protocol.JSON); + assertTrue(h.contains("msg.InsertEventHeader(\":content-type\", Aws::String(\"application/json\"));"), h); + assertTrue(h.contains("msg.WriteEventPayload(value.Jsonize().View().WriteCompact());"), h); + } + + @Test + void cborStructurePayload_usesCborEncodeAndApplicationCbor() { + String h = render(structurePayloadModel(), Protocol.CBOR); + assertTrue(h.contains("msg.InsertEventHeader(\":content-type\", Aws::String(\"application/cbor\"));"), h); + assertTrue(h.contains("value.CborEncode(encoder);"), h); + assertTrue(h.contains("msg.WriteEventPayload(encoder.GetEncodedData().ptr, encoder.GetEncodedData().len);"), h); + assertFalse(h.contains("Jsonize"), "CBOR must not use Jsonize: " + h); + } + + @Test + void explicitEventPayloadBlob_usesOctetStreamAndEmptyGuard() { + String h = render(blobPayloadModel(), Protocol.JSON); + assertTrue(h.contains("msg.InsertEventHeader(\":content-type\", Aws::String(\"application/octet-stream\"));"), h); + assertTrue(h.contains("if (!value.GetBytes().empty()) {"), h); + assertTrue(h.contains("msg.WriteEventPayload(value.GetBytes());"), h); + assertFalse(h.contains("Jsonize"), "Blob payload must not use Jsonize: " + h); + } +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ProtocolResolverTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ProtocolResolverTest.java index 354df389edeb..82c384335470 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ProtocolResolverTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ProtocolResolverTest.java @@ -14,14 +14,21 @@ class ProtocolResolverTest { @Test - void resolve_restJson1() { + void resolve_restJson1_mapsToRestJson() { ServiceShape service = ServiceShape.builder() .id("com.example#TestService") .version("2023-01-01") .addTrait(software.amazon.smithy.aws.traits.protocols.RestJson1Trait.builder().build()) .build(); Model model = Model.builder().addShape(service).build(); - assertEquals(Protocol.JSON, ProtocolResolver.resolve(service, model)); + assertEquals(Protocol.REST_JSON, ProtocolResolver.resolve(service, model)); + } + + @Test + void restJson_isJsonLike_andUsesJsonTraits() { + assertTrue(Protocol.REST_JSON.isJsonLike()); + assertTrue(ProtocolResolver.traitsFor(Protocol.REST_JSON) + instanceof com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.JsonProtocolTraits); } @Test @@ -112,12 +119,12 @@ void protocol_json_serializeMethodName() { @Test void protocol_cbor_serdeNamespace() { - assertEquals("Aws::Utils::Json", Protocol.CBOR.getSerdeNamespace()); + assertEquals("Aws::Utils::Cbor", Protocol.CBOR.getSerdeNamespace()); } @Test void protocol_cbor_viewType() { - assertEquals("Aws::Utils::Json::JsonView", Protocol.CBOR.getViewType()); + assertEquals("Aws::Utils::Cbor::CborValue", Protocol.CBOR.getViewType()); } @Test @@ -152,8 +159,8 @@ void protocol_json_isJsonLike() { } @Test - void protocol_cbor_isJsonLike() { - assertTrue(Protocol.CBOR.isJsonLike()); + void protocol_cbor_isNeitherJsonNorXmlLike() { + assertFalse(Protocol.CBOR.isJsonLike()); assertFalse(Protocol.CBOR.isXmlLike()); } @@ -178,11 +185,15 @@ void protocol_ec2_isXmlLike() { // ---------- traitsFor: the single protocol -> strategy selection point ---------- @Test - void traitsFor_jsonAndCbor_returnJsonTraits() { + void traitsFor_json_returnsJsonTraits() { assertInstanceOf(com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol .JsonProtocolTraits.class, ProtocolResolver.traitsFor(Protocol.JSON)); - assertInstanceOf(com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol - .JsonProtocolTraits.class, ProtocolResolver.traitsFor(Protocol.CBOR)); + } + + @Test + void cbor_usesCborTraits() { + assertTrue(ProtocolResolver.traitsFor(Protocol.CBOR) + instanceof com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.CborProtocolTraits); } @Test diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ProtocolTraitsCharacterizationTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ProtocolTraitsCharacterizationTest.java index 82e38cd32212..df51a773ed36 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ProtocolTraitsCharacterizationTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ProtocolTraitsCharacterizationTest.java @@ -43,6 +43,8 @@ class ProtocolTraitsCharacterizationTest { private static Trait traitFor(Protocol p) { switch (p) { case JSON: + return software.amazon.smithy.aws.traits.protocols.AwsJson1_0Trait.builder().build(); + case REST_JSON: return software.amazon.smithy.aws.traits.protocols.RestJson1Trait.builder().build(); case CBOR: return software.amazon.smithy.protocol.traits.Rpcv2CborTrait.builder().build(); @@ -63,18 +65,32 @@ private static Trait traitFor(Protocol p) { */ private static Model modelFor(Protocol p) { StringShape str = StringShape.builder().id("com.example#Str").build(); + software.amazon.smithy.model.shapes.IntegerShape intShape = + software.amazon.smithy.model.shapes.IntegerShape.builder().id("com.example#Int").build(); StructureShape nested = StructureShape.builder() .id("com.example#Nested") .addMember("value", str.getId()) .build(); + // Input carries a plain member, an httpHeader member, and an httpQuery member so + // both request Axis-1 predicates (header + query) fire. StructureShape input = StructureShape.builder() .id("com.example#DoThingInput") .addMember("name", str.getId()) .addMember("nested", nested.getId()) + .addMember(software.amazon.smithy.model.shapes.MemberShape.builder() + .id("com.example#DoThingInput$hdr").target(str.getId()) + .addTrait(new software.amazon.smithy.model.traits.HttpHeaderTrait("X-Thing")).build()) + .addMember(software.amazon.smithy.model.shapes.MemberShape.builder() + .id("com.example#DoThingInput$q").target(str.getId()) + .addTrait(new software.amazon.smithy.model.traits.HttpQueryTrait("q")).build()) .build(); + // Output carries a plain member and an httpResponseCode member. StructureShape output = StructureShape.builder() .id("com.example#DoThingOutput") .addMember("nested", nested.getId()) + .addMember(software.amazon.smithy.model.shapes.MemberShape.builder() + .id("com.example#DoThingOutput$status").target(intShape.getId()) + .addTrait(new software.amazon.smithy.model.traits.HttpResponseCodeTrait()).build()) .build(); OperationShape op = OperationShape.builder() .id("com.example#DoThing") @@ -87,7 +103,7 @@ private static Model modelFor(Protocol p) { .addTrait(traitFor(p)) .addOperation(op.getId()) .build(); - return Model.builder().addShapes(str, nested, input, output, op, service).build(); + return Model.builder().addShapes(str, intShape, nested, input, output, op, service).build(); } private static ServiceShape serviceOf(Model model) { @@ -147,7 +163,7 @@ void everyProtocol_generatesTheSameFileSet(Protocol p) { // ---------- sub-object: serde decls, includes, usings, fwd decls ---------- @ParameterizedTest - @EnumSource(value = Protocol.class, names = {"JSON", "CBOR"}) + @EnumSource(value = Protocol.class, names = {"JSON", "REST_JSON"}) void jsonLike_subObjectHeader_hasJsonSerdeDeclsAndFwdDecls(Protocol p) { String h = file(p, "Nested.h"); assertTrue(h.contains("AWS_EXAMPLE_API Nested() = default;"), h); @@ -159,6 +175,21 @@ void jsonLike_subObjectHeader_hasJsonSerdeDeclsAndFwdDecls(Protocol p) { assertFalse(h.contains("XmlNode"), "JSON-like header must not mention XML: " + h); } + @Test + void cbor_subObjectHeader_hasCborDecoderSerdeDeclsAndCborInclude() { + // CborSubObjectHeader.vm: streaming CborDecoder ctor/operator= + CborEncode, a hard + // include, and a CborValue forward declaration. NOT Jsonize/CborValue-arg. + String h = file(Protocol.CBOR, "Nested.h"); + assertTrue(h.contains("#include "), h); + assertTrue(h.contains( + "AWS_EXAMPLE_API Nested(const std::shared_ptr& decoder);"), h); + assertTrue(h.contains( + "AWS_EXAMPLE_API Nested& operator=(const std::shared_ptr& decoder);"), h); + assertTrue(h.contains("AWS_EXAMPLE_API void CborEncode(Aws::Crt::Cbor::CborEncoder& encoder) const;"), h); + assertTrue(h.contains("class CborValue;"), h); + assertFalse(h.contains("Jsonize"), "CBOR header must not mention Jsonize: " + h); + } + @Test void restXml_subObjectHeader_hasAddToNodeAndXmlNodeFwdDecl() { String h = file(Protocol.REST_XML, "Nested.h"); @@ -169,6 +200,24 @@ void restXml_subObjectHeader_hasAddToNodeAndXmlNodeFwdDecl() { assertFalse(h.contains("Jsonize"), "REST_XML header must not mention Jsonize: " + h); } + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"QUERY_XML", "EC2"}) + void queryLike_subObjectHeader_forwardDeclaresOStreamViaAWSStreamFwd(Protocol p) { + // Query/EC2 sub-objects declare OutputToStream(Aws::OStream&, ...), so the header must + // include AWSStreamFwd.h to forward-declare Aws::OStream, matching C2J. + String h = file(p, "Nested.h"); + assertTrue(h.contains("#include "), h); + } + + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"JSON", "REST_JSON", "REST_XML", "CBOR"}) + void nonQuery_subObjectHeader_omitsAWSStreamFwd(Protocol p) { + // Only Query/EC2 sub-objects emit OutputToStream; other protocols must not pull in + // AWSStreamFwd.h. + String h = file(p, "Nested.h"); + assertFalse(h.contains("AWSStreamFwd.h"), h); + } + @ParameterizedTest @EnumSource(value = Protocol.class, names = {"QUERY_XML", "EC2"}) void queryLike_subObjectHeader_hasBothOutputToStreamOverloads(Protocol p) { @@ -183,7 +232,7 @@ void queryLike_subObjectHeader_hasBothOutputToStreamOverloads(Protocol p) { } @ParameterizedTest - @EnumSource(value = Protocol.class, names = {"JSON", "CBOR"}) + @EnumSource(value = Protocol.class, names = {"JSON", "REST_JSON"}) void jsonLike_subObjectSource_hasJsonIncludeUsingAndStubs(Protocol p) { String c = file(p, "Nested.cpp"); assertTrue(c.contains("#include "), c); @@ -221,7 +270,7 @@ void queryLike_subObjectSource_hasBothOutputToStreamBodies(Protocol p) { // ---------- result: AmazonWebServiceResult<> payload type ---------- @ParameterizedTest - @EnumSource(value = Protocol.class, names = {"JSON", "CBOR"}) + @EnumSource(value = Protocol.class, names = {"JSON", "REST_JSON"}) void jsonLike_resultHeader_usesJsonValuePayloadAndForwardDeclaresJsonValue(Protocol p) { String h = file(p, "DoThingResult.h"); assertTrue(h.contains("AWS_EXAMPLE_API DoThingResult(const " @@ -248,7 +297,39 @@ void xmlLike_resultHeader_usesXmlDocumentPayloadAndForwardDeclaresXmlDocument(Pr } @ParameterizedTest - @EnumSource(value = Protocol.class, names = {"JSON", "CBOR"}) + @EnumSource(value = Protocol.class, names = {"JSON", "REST_JSON", "CBOR"}) + void jsonAndCbor_resultSource_includesUnreferencedParam(Protocol p) { + // C2J JSON/REST-JSON/CBOR result templates include UnreferencedParam.h; XML-family does not. + String c = file(p, "DoThingResult.cpp"); + assertTrue(c.contains("#include "), c); + } + + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"REST_XML", "QUERY_XML", "EC2"}) + void xmlLike_resultSource_omitsUnreferencedParam(Protocol p) { + // C2J XML-family result templates (rest-xml, query, ec2) do not include UnreferencedParam.h. + String c = file(p, "DoThingResult.cpp"); + assertFalse(c.contains("UnreferencedParam.h"), c); + } + + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"JSON", "REST_JSON", "REST_XML", "CBOR"}) + void nonQuery_resultSource_includesAWSStringStream(Protocol p) { + // C2J emits AWSStringStream.h in JSON/REST-JSON/REST-XML/CBOR result sources. + String c = file(p, "DoThingResult.cpp"); + assertTrue(c.contains("#include "), c); + } + + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"QUERY_XML", "EC2"}) + void queryLike_resultSource_omitsAWSStringStream(Protocol p) { + // Query/EC2 result sources build no string stream, so they omit AWSStringStream.h. + String c = file(p, "DoThingResult.cpp"); + assertFalse(c.contains("AWSStringStream.h"), c); + } + + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"JSON", "REST_JSON"}) void jsonLike_resultSource_hasJsonUsingsAndCtorImpls(Protocol p) { String c = file(p, "DoThingResult.cpp"); assertTrue(c.contains("#include "), c); @@ -277,7 +358,7 @@ void xmlLike_resultSource_hasXmlUsingsAndCtorImpls(Protocol p) { // ---------- request: only the serde include + usings are protocol-specific ---------- @ParameterizedTest - @EnumSource(value = Protocol.class, names = {"JSON", "CBOR"}) + @EnumSource(value = Protocol.class, names = {"JSON", "REST_JSON"}) void jsonLike_requestSource_hasJsonIncludeAndUsings(Protocol p) { String c = file(p, "DoThingRequest.cpp"); assertTrue(c.contains("#include "), c); @@ -287,22 +368,190 @@ void jsonLike_requestSource_hasJsonIncludeAndUsings(Protocol p) { assertFalse(c.contains("XmlSerializer.h"), c); } - @ParameterizedTest - @EnumSource(value = Protocol.class, names = {"REST_XML", "QUERY_XML", "EC2"}) - void xmlLike_requestSource_hasXmlIncludeAndUsings(Protocol p) { - String c = file(p, "DoThingRequest.cpp"); + @Test + void restXml_requestSource_hasXmlIncludeAndUsings() { + String c = file(Protocol.REST_XML, "DoThingRequest.cpp"); assertTrue(c.contains("#include "), c); assertTrue(c.contains("using namespace Aws::Utils::Xml;"), c); assertFalse(c.contains("JsonSerializer.h"), c); } - /** The request header is protocol-agnostic today; pin that so a regression is loud. */ + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"QUERY_XML", "EC2"}) + void queryLike_requestSource_usesStringStreamNotXmlSerializer(Protocol p) { + // Query/EC2 request bodies serialize to a query string (Action=...&Version=...), so the + // source uses StringUtils + AWSStringStream and NOT the XML serializer, matching C2J + // (QueryRequestSource.vm). The XML serde headers belong to the result/sub-object files. + String c = file(p, "DoThingRequest.cpp"); + assertTrue(c.contains("#include "), c); + assertTrue(c.contains("#include "), c); + assertFalse(c.contains("XmlSerializer.h"), c); + assertFalse(c.contains("using namespace Aws::Utils::Xml;"), c); + assertFalse(c.contains("JsonSerializer.h"), c); + // Query/EC2 request sources do not include (C2J QueryRequestSource.vm omits it). + assertFalse(c.contains("#include "), c); + } + + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"JSON", "REST_JSON", "REST_XML", "CBOR"}) + void nonQuery_requestSource_includesUtility(Protocol p) { + // JSON/REST-JSON/REST-XML/CBOR request sources include for std::forward/move. + String c = file(p, "DoThingRequest.cpp"); + assertTrue(c.contains("#include "), c); + } + + /** Every protocol's request emits SerializePayload and never leaks serde headers. */ @ParameterizedTest @EnumSource(Protocol.class) - void requestHeader_isProtocolAgnostic(Protocol p) { + void requestHeader_alwaysHasSerializePayload_neverSerdeIncludes(Protocol p) { String h = file(p, "DoThingRequest.h"); assertTrue(h.contains("Aws::String SerializePayload() const override;"), h); assertFalse(h.contains("JsonSerializer.h"), "Request header must not include serde headers: " + h); assertFalse(h.contains("XmlSerializer.h"), "Request header must not include serde headers: " + h); } + + // ---------- per-protocol request surface (fixture has header + query + status members) ---------- + + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"JSON"}) + void awsJson_request_hasTargetHeaderAndQueryAndSerialize(Protocol p) { + String h = file(p, "DoThingRequest.h"); + assertTrue(h.contains("SerializePayload() const override;"), h); + assertTrue(h.contains("GetRequestSpecificHeaders() const override;"), h); // header member OR target + assertTrue(h.contains("AddQueryStringParameters(Aws::Http::URI& uri) const override;"), h); + assertFalse(h.contains("DumpBodyToUrl"), h); + } + + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"REST_JSON", "REST_XML"}) + void restProtocols_request_headerFromMemberOnly_noTarget_noDump(Protocol p) { + String c = file(p, "DoThingRequest.cpp"); + assertFalse(c.contains("X-Amz-Target"), c); // rest protocols never target + String h = file(p, "DoThingRequest.h"); + assertTrue(h.contains("GetRequestSpecificHeaders() const override;"), h); // fixture has header member + assertTrue(h.contains("AddQueryStringParameters(Aws::Http::URI& uri) const override;"), h); + assertFalse(h.contains("DumpBodyToUrl"), h); + } + + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"QUERY_XML", "EC2"}) + void queryProtocols_request_haveProtectedDumpBodyToUrl(Protocol p) { + String h = file(p, "DoThingRequest.h"); + assertTrue(h.contains("void DumpBodyToUrl(Aws::Http::URI& uri) const override;"), h); + assertTrue(h.contains("protected:"), h); + String c = file(p, "DoThingRequest.cpp"); + assertTrue(c.contains("uri.SetQueryString(SerializePayload());"), c); + } + + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"CBOR"}) + void cbor_request_noTargetHeader(Protocol p) { + String c = file(p, "DoThingRequest.cpp"); + assertFalse(c.contains("X-Amz-Target"), c); + } + + // ---------- per-protocol result surface ---------- + + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"JSON", "REST_JSON"}) + void jsonResults_useJsonValue(Protocol p) { + String h = file(p, "DoThingResult.h"); + assertTrue(h.contains("AmazonWebServiceResult"), h); + assertFalse(h.contains("HasBeenSet() const"), h); // JSON results hide HasBeenSet + } + + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"CBOR"}) + void cborResults_useCborValueAndHideHasBeenSet(Protocol p) { + String h = file(p, "DoThingResult.h"); + assertTrue(h.contains("AmazonWebServiceResult"), h); + // CborResultHeader.vm sets useRequiredField=false, so CBOR results hide HasBeenSet too. + assertFalse(h.contains("HasBeenSet() const"), h); + } + + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"REST_XML", "QUERY_XML", "EC2"}) + void xmlResults_useXmlDocument(Protocol p) { + String h = file(p, "DoThingResult.h"); + assertTrue(h.contains("AmazonWebServiceResult"), h); + } + + @ParameterizedTest + @EnumSource(Protocol.class) + void allResults_setStatusCodeMemberFromResponseCode(Protocol p) { + String c = file(p, "DoThingResult.cpp"); + assertTrue(c.contains("m_status = static_cast(result.GetResponseCode());"), c); + } + + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"JSON", "REST_JSON", "REST_XML", "CBOR"}) + void nonQueryResultHeader_hasTopLevelRequestId(Protocol p) { + // JSON/REST-XML/CBOR results expose a top-level GetRequestId, matching C2J. + String h = file(p, "DoThingResult.h"); + assertTrue(h.contains("inline const Aws::String& GetRequestId() const"), h); + assertTrue(h.contains("Aws::String m_requestId;"), h); + } + + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"QUERY_XML", "EC2"}) + void queryLikeResultHeader_omitsTopLevelRequestId(Protocol p) { + // Query/EC2 results carry RequestId inside ResponseMetadata, so they must NOT expose a + // top-level GetRequestId / m_requestId, matching C2J. + String h = file(p, "DoThingResult.h"); + assertFalse(h.contains("GetRequestId"), h); + assertFalse(h.contains("m_requestId"), h); + } + + /** Collapses each line to its trailing content, ignoring leading indentation. */ + private static String stripIndent(String s) { + return s.replaceAll("(?m)^[ \\t]+", ""); + } + + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"QUERY_XML", "EC2"}) + void queryLikeResultHeader_noBlankBeforeHttpResponseCodeWhenNoRequestId(Protocol p) { + // Without a top-level m_requestId, the last data member is followed directly by + // m_HttpResponseCode (no intervening blank line), matching C2J. The fixture's last + // result member is the @httpResponseCode int "status". + String h = stripIndent(file(p, "DoThingResult.h")); + assertTrue(h.contains("int m_status{0};\nAws::Http::HttpResponseCode m_HttpResponseCode;"), h); + } + + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"JSON", "REST_JSON", "REST_XML", "CBOR"}) + void nonQueryResultHeader_blankLinePrecedesRequestId(Protocol p) { + // With a top-level m_requestId, a blank line separates the data members from the + // m_requestId / m_HttpResponseCode group, matching C2J. + String h = stripIndent(file(p, "DoThingResult.h")); + assertTrue(h.contains("\n\nAws::String m_requestId;\nAws::Http::HttpResponseCode m_HttpResponseCode;"), h); + } + + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"QUERY_XML", "EC2"}) + void queryLikeResultHeader_omitsAWSStringWhenNoStringMemberOrRequestId(Protocol p) { + // With no top-level m_requestId and no string-typed member, the Query/EC2 result header + // has no Aws::String use and must not include AWSString.h, matching C2J include hygiene. + // (The fixture DoThingOutput has only a nested struct + httpResponseCode int member.) + String h = file(p, "DoThingResult.h"); + assertFalse(h.contains("AWSString.h"), h); + } + + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"QUERY_XML", "EC2"}) + void queryLikeResultSource_includesLogMacrosForResponseMetadataDebug(Protocol p) { + // Query/EC2 result operator= emits AWS_LOGSTREAM_DEBUG / ResponseMetadata handling, + // so the source must include LogMacros.h and use the Logging namespace, matching C2J. + String c = file(p, "DoThingResult.cpp"); + assertTrue(c.contains("#include "), c); + assertTrue(c.contains("using namespace Aws::Utils::Logging;"), c); + } + + @ParameterizedTest + @EnumSource(value = Protocol.class, names = {"JSON", "REST_JSON", "REST_XML", "CBOR"}) + void nonQueryResultSource_omitsLogMacros(Protocol p) { + // Only Query/EC2 results reference the logging macros; other protocols must not + // pull in LogMacros.h. + String c = file(p, "DoThingResult.cpp"); + assertFalse(c.contains("LogMacros.h"), c); + } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RequestRendererTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RequestRendererTest.java index d0aefbb6bb61..94e9e0e107e8 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RequestRendererTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RequestRendererTest.java @@ -10,6 +10,7 @@ import org.junit.jupiter.api.Test; import software.amazon.smithy.build.MockManifest; import software.amazon.smithy.model.Model; +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.ShapeId; @@ -64,6 +65,10 @@ private static Model streamingModel(boolean inputStreams, boolean outputStreams) } private static String renderRequestHeaderForStreamingOp(boolean inputStreams, boolean outputStreams) { + return renderStreamingOp(inputStreams, outputStreams, "DoStreamRequest.h"); + } + + private static String renderStreamingOp(boolean inputStreams, boolean outputStreams, String fileSuffix) { Model model = streamingModel(inputStreams, outputStreams); ServiceShape service = model.expectShape(ShapeId.from("com.example#Example"), ServiceShape.class); MockManifest manifest = new MockManifest(); @@ -77,7 +82,7 @@ private static String renderRequestHeaderForStreamingOp(boolean inputStreams, bo delegator.flushWriters(); return manifest.getFileString( manifest.getFiles().stream() - .filter(p -> p.toString().endsWith("DoStreamRequest.h")) + .filter(p -> p.toString().endsWith(fileSuffix)) .findFirst().orElseThrow()) .orElseThrow(); } @@ -120,6 +125,50 @@ void bidirectionalRequest_alsoHasIsEventStreamRequest() { "Bidirectional op must also declare HasEventStreamResponse: " + h); } + @Test + void bidirectionalRequest_rendersEventStreamInputMemberAsSharedPtr() { + // C2J renders a request with an event-stream (input) member specially: an inline empty + // SerializePayload, a GetBody() override returning the encoded IOStream, and the member + // itself as a std::shared_ptr with a collision-renamed getter (GetMemberBody, + // because GetBody is reserved). The member has no templated setter and stores a shared_ptr. + String h = renderRequestHeaderForStreamingOp(true, true); + assertTrue(h.contains("#include "), "Missing include: " + h); + assertTrue(h.contains("Aws::String SerializePayload() const override { return {}; }"), + "Event-stream-input request must emit an inline empty SerializePayload: " + h); + assertTrue(h.contains("std::shared_ptr GetBody() const override;"), + "Missing GetBody() override: " + h); + assertTrue(h.contains("std::shared_ptr GetMemberBody() const { return m_body; }"), + "Event-stream member getter must be GetMemberBody returning shared_ptr: " + h); + assertTrue(h.contains("void SetBody(const std::shared_ptr& value) {"), + "Event-stream member setter must take a shared_ptr: " + h); + assertTrue(h.contains("WithBody(const std::shared_ptr& value)"), + "Event-stream member wither must take a shared_ptr: " + h); + assertTrue(h.contains("std::shared_ptr m_body;"), + "Event-stream member must be stored as shared_ptr: " + h); + assertTrue(h.contains("bool m_bodyHasBeenSet = false;"), + "Event-stream member must still have a HasBeenSet flag: " + h); + // Must NOT render the streaming member through the generic templated-setter path. + assertFalse(h.contains("template GetBody() const override;`, so the + // source MUST define it (returning the event-stream member) or linking fails. Matches C2J + // StreamRequestSource.vm. + String c = renderStreamingOp(true, true, "DoStreamRequest.cpp"); + assertTrue(c.contains( + "std::shared_ptr DoStreamRequest::GetBody() const { return m_body; }"), + "Bidirectional request source must define GetBody() returning the event-stream member: " + c); + // C2J's event-stream request source pulls AmazonWebServiceResult.h and the Stream/Aws + // usings rather than the JSON serde header. + assertTrue(c.contains("#include "), c); + assertTrue(c.contains("using namespace Aws::Utils::Stream;"), c); + } + @Test void nonStreamingRequest_hasNoEventStreamAugmentation() { String h = renderRequestHeaderForStreamingOp(false, false); @@ -127,4 +176,130 @@ void nonStreamingRequest_hasNoEventStreamAugmentation() { assertFalse(h.contains("GetEventStreamDecoder"), "Non-streaming request must be clean: " + h); assertFalse(h.contains("IsEventStreamRequest"), "Non-streaming request must be clean: " + h); } + + private static Model queryMemberModel() { + StringShape str = StringShape.builder().id("com.example#String").build(); + StructureShape input = StructureShape.builder() + .id("com.example#DoThingInput") + .addMember(MemberShape.builder() + .id("com.example#DoThingInput$filter").target(str.getId()) + .addTrait(new software.amazon.smithy.model.traits.HttpQueryTrait("filter")).build()) + .build(); + StructureShape output = StructureShape.builder() + .id("com.example#DoThingOutput").addMember("r", str.getId()).build(); + OperationShape op = OperationShape.builder() + .id("com.example#DoThing").input(input.getId()).output(output.getId()) + .addTrait(software.amazon.smithy.aws.traits.protocols.RestJson1Trait.builder().build()) + .build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#Example").version("2024-01-01") + .addTrait(software.amazon.smithy.aws.traits.protocols.RestJson1Trait.builder().build()) + .addOperation(op.getId()).build(); + return Model.builder().addShapes(str, input, output, op, service).build(); + } + + /** + * Request headers must NOT include {@code } even when they declare + * URI-taking methods: the base {@code AmazonWebServiceRequest.h} forward-declares + * {@code Aws::Http::URI}, which suffices for a reference parameter, and C2J omits the + * include. Emitting it would break byte-parity with the C2J output. + */ + @Test + void requestWithQueryMember_doesNotIncludeUriHeader() { + Model model = queryMemberModel(); + ServiceShape service = model.expectShape(ShapeId.from("com.example#Example"), ServiceShape.class); + MockManifest manifest = new MockManifest(); + CppWriterDelegator delegator = new CppWriterDelegator(manifest); + Protocol protocol = ProtocolResolver.resolve(service, model); + new RequestRenderer( + ShapeClassifier.classify(model, service, protocol).requests(), + model, service, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example").render(delegator); + delegator.flushWriters(); + String h = manifest.getFileString(manifest.getFiles().stream() + .filter(p -> p.toString().endsWith("DoThingRequest.h")).findFirst().orElseThrow()).orElseThrow(); + assertFalse(h.contains("#include "), h); + } + + /** Operation whose input has an @httpPayload blob body + a contentType header + a plain member. */ + private static Model rawStreamingPayloadRequestModel() { + StringShape str = StringShape.builder().id("com.example#String").build(); + software.amazon.smithy.model.shapes.BlobShape blob = + software.amazon.smithy.model.shapes.BlobShape.builder().id("com.example#Body").build(); + StructureShape input = StructureShape.builder() + .id("com.example#DoStreamInput") + .addMember(MemberShape.builder() + .id("com.example#DoStreamInput$body").target(blob.getId()) + .addTrait(new software.amazon.smithy.model.traits.HttpPayloadTrait()).build()) + .addMember(MemberShape.builder() + .id("com.example#DoStreamInput$contentType").target(str.getId()) + .addTrait(new software.amazon.smithy.model.traits.HttpHeaderTrait("Content-Type")).build()) + .addMember("modelId", str.getId()) + .build(); + StructureShape output = StructureShape.builder() + .id("com.example#DoStreamOutput").addMember("r", str.getId()).build(); + OperationShape op = OperationShape.builder() + .id("com.example#DoStream").input(input.getId()).output(output.getId()).build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#Example").version("2024-01-01").addOperation(op.getId()).build(); + return Model.builder().addShapes(str, blob, input, output, op, service).build(); + } + + private static String renderRawStreamingPayloadRequest(String fileSuffix) { + Model model = rawStreamingPayloadRequestModel(); + ServiceShape service = model.expectShape(ShapeId.from("com.example#Example"), ServiceShape.class); + MockManifest manifest = new MockManifest(); + CppWriterDelegator delegator = new CppWriterDelegator(manifest); + Protocol protocol = ProtocolResolver.resolve(service, model); + new RequestRenderer( + ShapeClassifier.classify(model, service, protocol).requests(), + model, service, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example").render(delegator); + delegator.flushWriters(); + return manifest.getFileString(manifest.getFiles().stream() + .filter(p -> p.toString().endsWith(fileSuffix)).findFirst().orElseThrow()).orElseThrow(); + } + + @Test + void rawStreamingPayloadRequest_usesStreamingBaseClassAndDropsPayloadMembers() { + // C2J: a request with a raw streaming @httpPayload member derives from + // StreamingRequest, which supplies GetBody/SetBody and GetContentType/SetContentType. + // The payload member (body) and the contentType member are stripped, and SerializePayload + // is not emitted (the base handles the body). Other members (modelId) remain. + String h = renderRawStreamingPayloadRequest("DoStreamRequest.h"); + assertTrue(h.contains("class DoStreamRequest : public StreamingExampleRequest {"), + "Must derive from StreamingExampleRequest: " + h); + assertFalse(h.contains("GetBody") || h.contains("SetBody") || h.contains("m_body"), + "Payload member must be dropped (base provides GetBody/SetBody): " + h); + assertFalse(h.contains("GetContentType") || h.contains("m_contentType"), + "contentType member must be dropped (base provides GetContentType): " + h); + assertFalse(h.contains("SerializePayload"), + "SerializePayload must not be emitted for a streaming-payload request: " + h); + assertTrue(h.contains("GetModelId"), + "Non-payload members must still be rendered: " + h); + } + + @Test + void rawStreamingPayloadRequestSource_includesBlobAndHeaderSerdeIncludes() { + // The source scans ALL members (payload not filtered out there), so a blob payload pulls + // HashingUtils.h and a header member pulls AWSStringStream.h — matching C2J. + String c = renderRawStreamingPayloadRequest("DoStreamRequest.cpp"); + assertTrue(c.contains("#include "), + "Blob payload member must pull HashingUtils.h into the source: " + c); + assertTrue(c.contains("#include "), + "Header member must pull AWSStringStream.h into the source: " + c); + } + + @Test + void rawStreamingPayloadRequestSource_usesStreamIncludesNotJsonSerde() { + // C2J routes a streaming (httpPayload blob body) request through StreamRequestSource.vm: + // AmazonWebServiceResult.h + the Stream/Utils/Aws usings, and NOT the JSON serde header/using. + String c = renderRawStreamingPayloadRequest("DoStreamRequest.cpp"); + assertTrue(c.contains("#include "), c); + assertTrue(c.contains("using namespace Aws::Utils::Stream;"), c); + assertFalse(c.contains("#include "), + "Streaming-payload request source must not include the JSON serializer: " + c); + assertFalse(c.contains("using namespace Aws::Utils::Json;"), + "Streaming-payload request source must not use the Json namespace: " + c); + } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ResultRendererTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ResultRendererTest.java new file mode 100644 index 000000000000..de80120fd8de --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ResultRendererTest.java @@ -0,0 +1,274 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model; + +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers.ResultRenderer; +import org.junit.jupiter.api.Test; +import software.amazon.smithy.build.MockManifest; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.BlobShape; +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.ShapeId; +import software.amazon.smithy.model.shapes.StringShape; +import software.amazon.smithy.model.shapes.StructureShape; +import software.amazon.smithy.model.traits.HttpPayloadTrait; +import software.amazon.smithy.model.traits.StreamingTrait; +import software.amazon.smithy.model.traits.Trait; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ResultRendererTest { + + /** A one-member output operation under a service carrying the given protocol trait. */ + private static Model oneMemberOutputModel(Trait protocolTrait) { + StringShape str = StringShape.builder().id("com.example#Str").build(); + StructureShape input = StructureShape.builder() + .id("com.example#DoThingInput").addMember("name", str.getId()).build(); + StructureShape output = StructureShape.builder() + .id("com.example#DoThingOutput").addMember("field", str.getId()).build(); + OperationShape op = OperationShape.builder() + .id("com.example#DoThing").input(input.getId()).output(output.getId()).build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#Example").version("2024-01-01") + .addTrait(protocolTrait).addOperation(op.getId()).build(); + return Model.builder().addShapes(str, input, output, op, service).build(); + } + + private static String renderResultHeader(Trait protocolTrait) { + Model model = oneMemberOutputModel(protocolTrait); + ServiceShape service = model.expectShape(ShapeId.from("com.example#Example"), ServiceShape.class); + MockManifest manifest = new MockManifest(); + CppWriterDelegator delegator = new CppWriterDelegator(manifest); + Protocol protocol = ProtocolResolver.resolve(service, model); + new ResultRenderer( + ShapeClassifier.classify(model, service, protocol).results(), + model, service, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example").render(delegator); + delegator.flushWriters(); + return manifest.getFileString(manifest.getFiles().stream() + .filter(p -> p.toString().endsWith("DoThingResult.h")).findFirst().orElseThrow()).orElseThrow(); + } + + @Test + void cborResult_omitsHasBeenSetAccessors() { + // C2J's CborResultHeader.vm sets useRequiredField=false, so result classes never emit + // HasBeenSet() accessors — same as every other protocol. (Only sub-object and request + // headers set useRequiredField=true.) + String h = renderResultHeader(software.amazon.smithy.protocol.traits.Rpcv2CborTrait.builder().build()); + assertFalse(h.contains("HasBeenSet() const"), h); + } + + @Test + void jsonResult_omitsHasBeenSetAccessors() { + String h = renderResultHeader(software.amazon.smithy.aws.traits.protocols.RestJson1Trait.builder().build()); + assertFalse(h.contains("HasBeenSet() const"), h); + } + + /** A GetBlob operation whose output binds a @httpPayload @streaming blob member "body". */ + private static Model streamingResultModel() { + StringShape str = StringShape.builder().id("com.example#Str").build(); + BlobShape blob = BlobShape.builder() + .id("com.example#StreamBlob").addTrait(new StreamingTrait()).build(); + StructureShape input = StructureShape.builder() + .id("com.example#GetBlobInput").addMember("name", str.getId()).build(); + StructureShape output = StructureShape.builder() + .id("com.example#GetBlobOutput") + .addMember(MemberShape.builder() + .id("com.example#GetBlobOutput$body").target(blob.getId()) + .addTrait(new HttpPayloadTrait()).build()) + .build(); + OperationShape op = OperationShape.builder() + .id("com.example#GetBlob").input(input.getId()).output(output.getId()).build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#Example").version("2024-01-01") + .addTrait(software.amazon.smithy.aws.traits.protocols.RestXmlTrait.builder().build()) + .addOperation(op.getId()).build(); + return Model.builder().addShapes(str, blob, input, output, op, service).build(); + } + + private static String renderStreaming(String fileSuffix) { + Model model = streamingResultModel(); + ServiceShape service = model.expectShape(ShapeId.from("com.example#Example"), ServiceShape.class); + MockManifest manifest = new MockManifest(); + CppWriterDelegator delegator = new CppWriterDelegator(manifest); + Protocol protocol = ProtocolResolver.resolve(service, model); + new ResultRenderer( + ShapeClassifier.classify(model, service, protocol).results(), + model, service, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example").render(delegator); + delegator.flushWriters(); + return manifest.getFileString(manifest.getFiles().stream() + .filter(p -> p.toString().endsWith(fileSuffix)).findFirst().orElseThrow()).orElseThrow(); + } + + @Test + void streamingResult_isMoveOnlyWithResponseStream() { + String h = renderStreaming("GetBlobResult.h"); + assertTrue(h.contains("GetBlobResult(GetBlobResult&&) = default;"), h); + assertTrue(h.contains("GetBlobResult& operator=(GetBlobResult&&) = default;"), h); + assertTrue(h.contains("GetBlobResult(const GetBlobResult&) = delete;"), h); + assertTrue(h.contains("Aws::AmazonWebServiceResult&& result"), h); + assertTrue(h.contains("#include "), h); + assertTrue(h.contains("Aws::IOStream& GetBody() const"), h); + assertTrue(h.contains("void ReplaceBody(Aws::IOStream* body)"), h); + assertFalse(h.contains("SetBody"), h); + } + + @Test + void streamingResultSource_takesOwnershipOfPayload() { + String cpp = renderStreaming("GetBlobResult.cpp"); + assertTrue(cpp.contains("m_body = result.TakeOwnershipOfPayload();"), cpp); + } + + @Test + void streamingResultSource_blobPayloadIncludesHashingUtils() { + // The blob payload member pulls HashingUtils.h into the source (C2J computeSourceIncludes). + String cpp = renderStreaming("GetBlobResult.cpp"); + assertTrue(cpp.contains("#include "), cpp); + } + + /** + * A GetStream operation whose output binds a @httpPayload @streaming blob member with the + * given name, optionally alongside an @httpResponseCode integer member "statusCode". + */ + private static Model streamingResultModel(String payloadMemberName, boolean withStatusCode) { + StringShape str = StringShape.builder().id("com.example#Str").build(); + BlobShape blob = BlobShape.builder() + .id("com.example#StreamBlob").addTrait(new StreamingTrait()).build(); + software.amazon.smithy.model.shapes.IntegerShape intShape = + software.amazon.smithy.model.shapes.IntegerShape.builder().id("com.example#Int").build(); + StructureShape input = StructureShape.builder() + .id("com.example#GetStreamInput").addMember("name", str.getId()).build(); + StructureShape.Builder outputBuilder = StructureShape.builder() + .id("com.example#GetStreamOutput") + .addMember(MemberShape.builder() + .id("com.example#GetStreamOutput$" + payloadMemberName).target(blob.getId()) + .addTrait(new HttpPayloadTrait()) + .addTrait(new software.amazon.smithy.model.traits.RequiredTrait()).build()); + if (withStatusCode) { + outputBuilder.addMember(MemberShape.builder() + .id("com.example#GetStreamOutput$statusCode").target(intShape.getId()) + .addTrait(new software.amazon.smithy.model.traits.HttpResponseCodeTrait()).build()); + } + StructureShape output = outputBuilder.build(); + OperationShape op = OperationShape.builder() + .id("com.example#GetStream").input(input.getId()).output(output.getId()).build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#Example").version("2024-01-01") + .addTrait(software.amazon.smithy.aws.traits.protocols.RestJson1Trait.builder().build()) + .addOperation(op.getId()).build(); + return Model.assembler().addShapes(str, blob, intShape, input, output, op, service).assemble().unwrap(); + } + + /** Same as the named-member model, but the payload member carries documentation. */ + private static Model documentedStreamingResultModel() { + StringShape str = StringShape.builder().id("com.example#Str").build(); + BlobShape blob = BlobShape.builder() + .id("com.example#StreamBlob").addTrait(new StreamingTrait()).build(); + StructureShape input = StructureShape.builder() + .id("com.example#GetStreamInput").addMember("name", str.getId()).build(); + StructureShape output = StructureShape.builder() + .id("com.example#GetStreamOutput") + .addMember(MemberShape.builder() + .id("com.example#GetStreamOutput$body").target(blob.getId()) + .addTrait(new HttpPayloadTrait()) + .addTrait(new software.amazon.smithy.model.traits.DocumentationTrait( + "

    Inference response from the model.

    ")).build()) + .build(); + OperationShape op = OperationShape.builder() + .id("com.example#GetStream").input(input.getId()).output(output.getId()).build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#Example").version("2024-01-01") + .addTrait(software.amazon.smithy.aws.traits.protocols.RestJson1Trait.builder().build()) + .addOperation(op.getId()).build(); + return Model.builder().addShapes(str, blob, input, output, op, service).build(); + } + + @Test + void streamingResult_payloadAccessorRendersMemberDoc() { + // C2J emits the streaming payload member's @documentation above GetBody(); the smithy + // streaming-header path must too (it was previously dropped for the hand-written accessor). + String h = renderResultSource(documentedStreamingResultModel(), "GetStreamResult.h"); + assertTrue(h.contains("Inference response from the model."), + "Streaming payload accessor must render the member doc comment: " + h); + // The doc must precede the getter, inside the ///@{ group. + int doc = h.indexOf("Inference response from the model."); + int getter = h.indexOf("Aws::IOStream& GetBody() const"); + assertTrue(doc >= 0 && getter >= 0 && doc < getter, + "Doc comment must come before GetBody(): " + h); + } + + @Test + void streamingResult_payloadAccessorNamedAfterMember() { + String h = renderResultSource(streamingResultModel("audioStream", false), "GetStreamResult.h"); + assertTrue(h.contains("Aws::IOStream& GetAudioStream() const { return m_audioStream.GetUnderlyingStream(); }"), h); + // ReplaceBody stays literal regardless of member name, matching C2J StreamResultHeader.vm. + assertTrue(h.contains("void ReplaceBody(Aws::IOStream* body) { m_audioStream = "), h); + assertTrue(h.contains("Aws::Utils::Stream::ResponseStream m_audioStream{};"), h); + assertTrue(h.contains("bool m_audioStreamHasBeenSet = false;"), h); + assertFalse(h.contains("m_body"), h); + } + + @Test + void streamingResultSource_payloadFieldNamedAfterMember() { + String cpp = renderResultSource(streamingResultModel("audioStream", false), "GetStreamResult.cpp"); + assertTrue(cpp.contains("m_audioStream = result.TakeOwnershipOfPayload();"), cpp); + assertTrue(cpp.contains("m_audioStreamHasBeenSet = true;"), cpp); + assertFalse(cpp.contains("m_body"), cpp); + } + + @Test + void streamingResultSource_setsStatusCodeMember() { + String cpp = renderResultSource(streamingResultModel("body", true), "GetStreamResult.cpp"); + assertTrue(cpp.contains("m_statusCode = static_cast(result.GetResponseCode());"), cpp); + assertTrue(cpp.contains("m_statusCodeHasBeenSet = true;"), cpp); + } + + /** A rest-json operation whose output has an @httpResponseCode integer member "status". */ + private static Model statusCodeResultModel() { + software.amazon.smithy.model.shapes.IntegerShape intShape = + software.amazon.smithy.model.shapes.IntegerShape.builder().id("com.example#Int").build(); + StructureShape input = StructureShape.builder() + .id("com.example#StatInput").build(); + StructureShape output = StructureShape.builder() + .id("com.example#StatOutput") + .addMember(MemberShape.builder() + .id("com.example#StatOutput$status").target(intShape.getId()) + .addTrait(new software.amazon.smithy.model.traits.HttpResponseCodeTrait()).build()) + .build(); + OperationShape op = OperationShape.builder() + .id("com.example#Stat").input(input.getId()).output(output.getId()).build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#Example").version("2024-01-01") + .addTrait(software.amazon.smithy.aws.traits.protocols.RestJson1Trait.builder().build()) + .addOperation(op.getId()).build(); + return Model.assembler().addShapes(intShape, input, output, op, service).assemble().unwrap(); + } + + private static String renderResultSource(Model model, String fileSuffix) { + ServiceShape service = model.expectShape(ShapeId.from("com.example#Example"), ServiceShape.class); + MockManifest manifest = new MockManifest(); + CppWriterDelegator delegator = new CppWriterDelegator(manifest); + Protocol protocol = ProtocolResolver.resolve(service, model); + new ResultRenderer( + ShapeClassifier.classify(model, service, protocol).results(), + model, service, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example").render(delegator); + delegator.flushWriters(); + return manifest.getFileString(manifest.getFiles().stream() + .filter(p -> p.toString().endsWith(fileSuffix)).findFirst().orElseThrow()).orElseThrow(); + } + + @Test + void statusCodeMember_setFromResponseCode() { + String cpp = renderResultSource(statusCodeResultModel(), "StatResult.cpp"); + assertTrue(cpp.contains("m_status = static_cast(result.GetResponseCode());"), cpp); + } +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SerdeStubTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SerdeStubTest.java new file mode 100644 index 000000000000..2335c427e3a8 --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SerdeStubTest.java @@ -0,0 +1,49 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model; + +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class SerdeStubTest { + + @Test + void renderEventPayloadDecodeStub_emitsTodoAndNoProtocolTokens() { + CppWriter writer = new CppWriter(); + SerdeStub.renderEventPayloadDecodeStub(writer, "SubscribeToShardEvent", "m_onSubscribeToShardEvent"); + String out = writer.toString(); + assertTrue(out.contains("// TODO: protocol-specific event payload deserialization"), + "Missing TODO marker: " + out); + assertTrue(out.contains("m_onSubscribeToShardEvent(SubscribeToShardEvent{});"), + "Missing callback invocation: " + out); + assertFalse(out.contains("JsonValue"), "Should not emit JSON tokens: " + out); + assertFalse(out.contains("Cbor"), "Should not emit CBOR tokens: " + out); + } + + @Test + void renderErrorPayloadParseStub_emitsTodoOnly() { + CppWriter writer = new CppWriter(); + SerdeStub.renderErrorPayloadParseStub(writer); + String out = writer.toString(); + assertTrue(out.contains("// TODO: protocol-specific error payload deserialization"), + "Missing TODO marker: " + out); + assertFalse(out.contains("JsonView"), "Should not emit JSON tokens: " + out); + } + + @Test + void renderSerdeSourceStub_json_emitsEmptyBodies() { + CppWriter writer = new CppWriter(); + SerdeStub.renderSerdeSourceStub(writer, Protocol.JSON, "SubscribeToShardEventStream"); + String out = writer.toString(); + assertTrue(out.contains("SubscribeToShardEventStream::SubscribeToShardEventStream(JsonView jsonValue)"), + "Missing JSON ctor stub: " + out); + assertTrue(out.contains("JsonValue SubscribeToShardEventStream::Jsonize() const"), + "Missing Jsonize stub: " + out); + } +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ShapeClassifierTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ShapeClassifierTest.java index d74f17b29a7e..9e028dbf7a49 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ShapeClassifierTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ShapeClassifierTest.java @@ -279,6 +279,26 @@ private static Model modelWithStreaming(boolean inputStreams, boolean outputStre return Model.builder().addShapes(str, eventStream, input, output, op).build(); } + @Test + void outgoingEventStreams_collectsInputBoundStreamingUnions() { + // A @streaming union bound to a request INPUT is an outgoing event stream (encoder), + // classified separately from output-bound streaming unions (which become handlers). + Model model = modelWithStreaming(true, false); + ServiceShape service = ServiceShape.builder().id("com.example#Svc").version("2024-01-01") + .addOperation(ShapeId.from("com.example#Op")).build(); + // Re-assemble with a service so classify() has a root. + Model withSvc = model.toBuilder().addShape(service).build(); + var classified = ShapeClassifier.classify(withSvc, service, ProtocolResolver.resolve(service, withSvc)); + assertTrue(classified.outgoingEventStreams().stream() + .anyMatch(s -> s.getId().getName().equals("EventStream")), + "Input-bound @streaming union must be collected as an outgoing event stream: " + + classified.outgoingEventStreams()); + // And it must NOT also land in subObjects (which would double-render it as a data union). + assertTrue(classified.subObjects().stream() + .noneMatch(s -> s.getId().getName().equals("EventStream")), + "Outgoing event stream must not also be a sub-object: " + classified.subObjects()); + } + @Test void isEventStreamResponseOperation_trueWhenOutputStreams() { Model model = modelWithStreaming(false, true); @@ -303,6 +323,107 @@ void isEventStreamResponseOperation_falseWhenNeitherStreams() { assertFalse(ShapeClassifier.isEventStreamRequestOperation(op, model)); } + private static Model streamingBlobOutputModel(boolean streaming) { + StringShape str = StringShape.builder().id("com.example#String").build(); + BlobShape.Builder blobBuilder = BlobShape.builder().id("com.example#StreamBlob"); + if (streaming) { + blobBuilder.addTrait(new StreamingTrait()); + } + BlobShape blob = blobBuilder.build(); + StructureShape input = StructureShape.builder() + .id("com.example#GetBlobInput").addMember("name", str.getId()).build(); + StructureShape.Builder outputBuilder = StructureShape.builder().id("com.example#GetBlobOutput"); + if (streaming) { + outputBuilder.addMember(MemberShape.builder() + .id("com.example#GetBlobOutput$body").target(blob.getId()) + .addTrait(new HttpPayloadTrait()).build()); + } else { + outputBuilder.addMember("result", str.getId()); + } + StructureShape output = outputBuilder.build(); + OperationShape op = OperationShape.builder() + .id("com.example#GetBlob").input(input.getId()).output(output.getId()).build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#Svc").version("2024-01-01").addOperation(op.getId()).build(); + return Model.builder().addShapes(str, blob, input, output, op, service).build(); + } + + @Test + void streamingBlobPayloadOutput_isClassifiedStreaming() { + Model model = streamingBlobOutputModel(true); + ServiceShape svc = model.expectShape(ShapeId.from("com.example#Svc"), ServiceShape.class); + var results = ShapeClassifier.classify(model, svc, ProtocolResolver.resolve(svc, model)).results(); + assertTrue(results.stream().anyMatch(r -> r.operation().getId().getName().equals("GetBlob") && r.streaming())); + } + + @Test + void plainOutput_isNotStreaming() { + Model model = streamingBlobOutputModel(false); + ServiceShape svc = model.expectShape(ShapeId.from("com.example#Svc"), ServiceShape.class); + var results = ShapeClassifier.classify(model, svc, ProtocolResolver.resolve(svc, model)).results(); + assertTrue(results.stream().allMatch(r -> !r.streaming())); + } + + /** An @httpPayload blob or string member (with or without @streaming) that is NOT an event stream. */ + private static Model httpPayloadOutputModel(software.amazon.smithy.model.shapes.Shape payloadTarget) { + StringShape str = StringShape.builder().id("com.example#String").build(); + StructureShape input = StructureShape.builder() + .id("com.example#GetBlobInput").addMember("name", str.getId()).build(); + StructureShape output = StructureShape.builder().id("com.example#GetBlobOutput") + .addMember(MemberShape.builder() + .id("com.example#GetBlobOutput$body").target(payloadTarget.getId()) + .addTrait(new HttpPayloadTrait()).build()) + .build(); + OperationShape op = OperationShape.builder() + .id("com.example#GetBlob").input(input.getId()).output(output.getId()).build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#Svc").version("2024-01-01").addOperation(op.getId()).build(); + return Model.builder().addShapes(str, payloadTarget, input, output, op, service).build(); + } + + @Test + void httpPayloadBlobOutput_withoutStreamingTrait_isClassifiedStreaming() { + // C2J treats an @httpPayload blob as a streaming ResponseStream even without @streaming + // (CppViewHelper.isStreamingPayloadMember: isStreaming() OR blob OR string). + BlobShape blob = BlobShape.builder().id("com.example#Body").build(); + Model model = httpPayloadOutputModel(blob); + ServiceShape svc = model.expectShape(ShapeId.from("com.example#Svc"), ServiceShape.class); + var results = ShapeClassifier.classify(model, svc, ProtocolResolver.resolve(svc, model)).results(); + assertTrue(results.stream().anyMatch(r -> r.operation().getId().getName().equals("GetBlob") && r.streaming()), + "An @httpPayload blob without @streaming must classify streaming"); + } + + @Test + void httpPayloadStringOutput_isClassifiedStreaming() { + StringShape body = StringShape.builder().id("com.example#Body").build(); + Model model = httpPayloadOutputModel(body); + ServiceShape svc = model.expectShape(ShapeId.from("com.example#Svc"), ServiceShape.class); + var results = ShapeClassifier.classify(model, svc, ProtocolResolver.resolve(svc, model)).results(); + assertTrue(results.stream().anyMatch(r -> r.operation().getId().getName().equals("GetBlob") && r.streaming()), + "An @httpPayload string must classify streaming"); + } + + @Test + void noInputOperation_stillProducesRequest() { + StringShape str = StringShape.builder().id("com.example#Str").build(); + StructureShape output = StructureShape.builder() + .id("com.example#PingOutput").addMember("r", str.getId()).build(); + // No .input(...) -> Smithy defaults the input target to smithy.api#Unit + OperationShape op = OperationShape.builder() + .id("com.example#Ping").output(output.getId()).build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#Svc").version("2024-01-01").addOperation(op.getId()).build(); + // Assemble with the prelude so smithy.api#Unit (the default no-input target) resolves. + Model model = Model.assembler() + .addShapes(str, output, op, service) + .assemble().unwrap(); + + var requests = ShapeClassifier.classify(model, service, + ProtocolResolver.resolve(service, model)).requests(); + assertTrue(requests.stream().anyMatch(r -> r.operation().getId().getName().equals("Ping")), + "Expected a RequestInfo for the no-input operation Ping"); + } + @Test void classifiesEnumShape() { // StringShape with @enum trait -> classified as enum diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SubObjectRendererTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SubObjectRendererTest.java new file mode 100644 index 000000000000..198304fd0bbb --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SubObjectRendererTest.java @@ -0,0 +1,176 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model; + +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.ProtocolTraits; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers.SubObjectRenderer; +import org.junit.jupiter.api.Test; +import software.amazon.smithy.build.MockManifest; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.model.shapes.ShapeId; +import software.amazon.smithy.model.shapes.StringShape; +import software.amazon.smithy.model.shapes.StructureShape; +import software.amazon.smithy.model.shapes.UnionShape; +import software.amazon.smithy.model.traits.DocumentationTrait; +import software.amazon.smithy.model.traits.StreamingTrait; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Verifies that {@link SubObjectRenderer} renders C2J-style union shapes. In C2J a union is a + * {@code structure} with {@code "union": true} and is emitted by the same ModelClass templates + * as a plain structure (serde decls + per-member Get/Set/With/HasBeenSet accessors + private + * data members and flags). Non-streaming unions must produce header + source files; {@code + * @streaming} unions belong to the event-stream renderers and must be skipped here. + */ +class SubObjectRendererTest { + + /** + * A model with a plain structure sub-object, a non-streaming union, and a {@code @streaming} + * union — mirroring bedrock-runtime (ContentBlock / ToolChoice are data unions; + * InvokeModelWithBidirectionalStreamInput is a streaming union). + */ + private static Model model() { + StringShape str = StringShape.builder().id("com.example#Str").build(); + StructureShape leaf = StructureShape.builder() + .id("com.example#Leaf") + .addMember("value", str.getId()) + .build(); + // Non-streaming data union: one string variant, one struct variant, one with member doc. + UnionShape dataUnion = UnionShape.builder() + .id("com.example#ContentBlock") + .addTrait(new DocumentationTrait("

    A block of content.

    ")) + .addMember("text", str.getId(), + b -> b.addTrait(new DocumentationTrait("

    Text variant.

    "))) + .addMember("leaf", leaf.getId()) + .build(); + // Streaming union — handled by the event-stream renderers, not here. + UnionShape streamingUnion = UnionShape.builder() + .id("com.example#BidirectionalInput") + .addTrait(new StreamingTrait()) + .addMember("chunk", leaf.getId()) + .build(); + // Memberless structure (e.g. bedrock-runtime AnyToolChoice / AutoToolChoice): C2J emits + // no private: section when the shape has no members. + StructureShape empty = StructureShape.builder() + .id("com.example#AnyToolChoice") + .build(); + // Union with a blob member (e.g. bedrock-runtime AudioSource): its source needs + // HashingUtils.h for Base64 blob serde. + software.amazon.smithy.model.shapes.BlobShape blob = + software.amazon.smithy.model.shapes.BlobShape.builder().id("com.example#PartBody").build(); + UnionShape blobUnion = UnionShape.builder() + .id("com.example#AudioSource") + .addMember("bytes", blob.getId()) + .addMember("leaf", leaf.getId()) + .build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#Example") + .version("2024-01-01") + .build(); + return Model.builder() + .addShapes(str, leaf, dataUnion, streamingUnion, empty, blob, blobUnion, service).build(); + } + + private static java.util.Map renderAll() { + Model model = model(); + ServiceShape service = model.expectShape(ShapeId.from("com.example#Example"), ServiceShape.class); + MockManifest manifest = new MockManifest(); + CppWriterDelegator delegator = new CppWriterDelegator(manifest); + ProtocolTraits traits = ProtocolResolver.traitsFor(Protocol.JSON); + java.util.List subObjects = java.util.List.of( + model.expectShape(ShapeId.from("com.example#Leaf")), + model.expectShape(ShapeId.from("com.example#ContentBlock")), + model.expectShape(ShapeId.from("com.example#BidirectionalInput")), + model.expectShape(ShapeId.from("com.example#AnyToolChoice")), + model.expectShape(ShapeId.from("com.example#AudioSource"))); + new SubObjectRenderer(subObjects, model, service, traits, + "Example", "AWS_EXAMPLE_API", "Example", "example").render(delegator); + delegator.flushWriters(); + java.util.Map out = new java.util.TreeMap<>(); + for (java.nio.file.Path path : manifest.getFiles()) { + out.put(path.getFileName().toString(), manifest.getFileString(path).orElseThrow()); + } + return out; + } + + @Test + void nonStreamingUnion_generatesHeaderAndSource() { + java.util.Map files = renderAll(); + assertTrue(files.containsKey("ContentBlock.h"), + "Non-streaming union must generate a header: " + files.keySet()); + assertTrue(files.containsKey("ContentBlock.cpp"), + "Non-streaming union must generate a source: " + files.keySet()); + } + + @Test + void nonStreamingUnion_headerHasSerdeDeclsAndPerMemberAccessors() { + String h = renderAll().get("ContentBlock.h"); + // Same serde surface as a structure sub-object. + assertTrue(h.contains("AWS_EXAMPLE_API ContentBlock() = default;"), h); + assertTrue(h.contains("AWS_EXAMPLE_API ContentBlock(Aws::Utils::Json::JsonView jsonValue);"), h); + assertTrue(h.contains("AWS_EXAMPLE_API Aws::Utils::Json::JsonValue Jsonize() const;"), h); + // Per-member accessors for each variant. + assertTrue(h.contains("GetText") && h.contains("SetText") && h.contains("WithText"), h); + assertTrue(h.contains("GetLeaf") && h.contains("SetLeaf") && h.contains("WithLeaf"), h); + assertTrue(h.contains("bool m_textHasBeenSet = false;"), h); + assertTrue(h.contains("bool m_leafHasBeenSet = false;"), h); + // Class-level and member-level documentation flow through. + assertTrue(h.contains("A block of content."), h); + assertTrue(h.contains("Text variant."), h); + } + + @Test + void nonStreamingUnion_sourceHasSerdeImpls() { + String c = renderAll().get("ContentBlock.cpp"); + assertTrue(c.contains("ContentBlock::ContentBlock(JsonView jsonValue)"), c); + assertTrue(c.contains("ContentBlock& ContentBlock::operator=(JsonView jsonValue)"), c); + assertTrue(c.contains("JsonValue ContentBlock::Jsonize() const"), c); + } + + @Test + void blobMemberSource_includesHashingUtils() { + // A sub-object with a blob member needs HashingUtils.h in its source (Base64 blob serde), + // matching C2J's computeSourceIncludes. The header must NOT carry it (source-only include). + java.util.Map files = renderAll(); + String c = files.get("AudioSource.cpp"); + assertTrue(c.contains("#include "), + "Blob-bearing sub-object source must include HashingUtils.h: " + c); + String h = files.get("AudioSource.h"); + assertFalse(h.contains("HashingUtils.h"), + "HashingUtils.h is a source-only include, not a header include: " + h); + } + + @Test + void nonBlobSource_omitsHashingUtils() { + String c = renderAll().get("ContentBlock.cpp"); + assertFalse(c.contains("HashingUtils.h"), + "A sub-object without a blob member must not include HashingUtils.h: " + c); + } + + @Test + void memberlessShape_omitsPrivateSection() { + // C2J emits the private: section only when the shape has members + // (ModelClassMembersAndInlines.vm: `#if($shape.members.size() > 0 ...`). A memberless + // sub-object ends right after its serde decls — no trailing blank line and no private:. + String h = renderAll().get("AnyToolChoice.h"); + assertTrue(h.contains("AWS_EXAMPLE_API Aws::Utils::Json::JsonValue Jsonize() const;"), h); + assertFalse(h.contains("private:"), + "Memberless shape must not emit a private: section: " + h); + } + + @Test + void streamingUnion_isNotRenderedBySubObjectRenderer() { + java.util.Map files = renderAll(); + assertFalse(files.containsKey("BidirectionalInput.h"), + "Streaming union must NOT be rendered by SubObjectRenderer: " + files.keySet()); + assertFalse(files.containsKey("BidirectionalInput.cpp"), + "Streaming union must NOT be rendered by SubObjectRenderer: " + files.keySet()); + } +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraitsTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraitsTest.java new file mode 100644 index 000000000000..cb15313dee2f --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraitsTest.java @@ -0,0 +1,191 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol; + +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class CborProtocolTraitsTest { + + private static String render(java.util.function.Consumer body) { + CppWriter writer = new CppWriter(); + body.accept(writer); + return writer.toString(); + } + + private final ProtocolTraits cbor = new CborProtocolTraits(); + + private static software.amazon.smithy.model.shapes.StructureShape reqWith(boolean header, boolean query) { + software.amazon.smithy.model.shapes.StructureShape.Builder b = + software.amazon.smithy.model.shapes.StructureShape.builder().id("com.example#DoThingRequest"); + if (header) { + b.addMember(software.amazon.smithy.model.shapes.MemberShape.builder() + .id("com.example#DoThingRequest$h").target("com.example#Str") + .addTrait(new software.amazon.smithy.model.traits.HttpHeaderTrait("X-H")).build()); + } + if (query) { + b.addMember(software.amazon.smithy.model.shapes.MemberShape.builder() + .id("com.example#DoThingRequest$q").target("com.example#Str") + .addTrait(new software.amazon.smithy.model.traits.HttpQueryTrait("q")).build()); + } + return b.build(); + } + private static software.amazon.smithy.model.shapes.OperationShape opWithInput( + software.amazon.smithy.model.shapes.StructureShape req) { + return software.amazon.smithy.model.shapes.OperationShape.builder() + .id("com.example#DoThing").input(req.getId()).build(); + } + private static software.amazon.smithy.model.shapes.OperationShape opNoInput() { + return software.amazon.smithy.model.shapes.OperationShape.builder().id("com.example#Ping").build(); + } + private static software.amazon.smithy.model.shapes.StructureShape unitStructure() { + return software.amazon.smithy.model.shapes.StructureShape.builder() + .id("com.example#PingRequest").build(); + } + private static software.amazon.smithy.model.shapes.ServiceShape svcAthena() { + return software.amazon.smithy.model.shapes.ServiceShape.builder() + .id("com.example#AmazonAthena").version("2017-05-18").build(); + } + private static software.amazon.smithy.model.Model modelWith( + software.amazon.smithy.model.shapes.StructureShape req) { + return software.amazon.smithy.model.Model.builder() + .addShapes(software.amazon.smithy.model.shapes.StringShape.builder().id("com.example#Str").build(), req) + .build(); + } + + @Test + void serdeNamespace_isCbor() { + assertEquals("Aws::Utils::Cbor", cbor.serdeNamespace()); + } + + @Test + void resultForwardDecls_declareCborValue() { + String out = render(cbor::writeResultForwardDeclarations); + assertTrue(out.contains("class CborValue;"), out); + assertFalse(out.contains("JsonValue"), out); + } + + @Test + void serdeInclude_isCborHeaders() { + var out = cbor.serdeIncludes(FileKind.SUBOBJECT_SOURCE); + assertTrue(out.contains("aws/crt/cbor/Cbor.h"), out.toString()); + assertTrue(out.contains("aws/core/utils/cbor/CborValue.h"), out.toString()); + } + + // --- Sub-object serde contract: C2J CBOR uses a streaming CborDecoder/CborEncode, NOT the + // JSON-family CborValue/Jsonize shape. (CborSubObjectHeader.vm / CborSubObjectSource.vm) + + @Test + void subObjectHeader_includesCborHeader() { + // CborSubObjectHeader.vm hard-includes (the signatures reference + // Aws::Crt::Cbor::CborDecoder / CborEncoder directly). + assertTrue(cbor.serdeIncludes(FileKind.SUBOBJECT_HEADER).contains("aws/crt/cbor/Cbor.h"), + cbor.serdeIncludes(FileKind.SUBOBJECT_HEADER).toString()); + } + + @Test + void serdeMethodDecls_useCborDecoderAndCborEncode() { + String out = render(w -> cbor.writeSerdeMethodDecls(w, "AWS_EXAMPLE_API", "ArchiveRetention", null)); + assertTrue(out.contains( + "ArchiveRetention(const std::shared_ptr& decoder);"), out); + assertTrue(out.contains( + "ArchiveRetention& operator=(const std::shared_ptr& decoder);"), out); + assertTrue(out.contains("void CborEncode(Aws::Crt::Cbor::CborEncoder& encoder) const;"), out); + assertFalse(out.contains("Jsonize"), out); + assertFalse(out.contains("CborValue"), out); + } + + @Test + void serdeMethodImpls_useCborDecoderAndCborEncode() { + String out = render(w -> cbor.writeSerdeMethodImpls(w, "ArchiveRetention")); + assertTrue(out.contains( + "ArchiveRetention::ArchiveRetention(const std::shared_ptr& decoder)"), out); + assertTrue(out.contains( + "ArchiveRetention& ArchiveRetention::operator=(const std::shared_ptr& decoder)"), + out); + assertTrue(out.contains("void ArchiveRetention::CborEncode(Aws::Crt::Cbor::CborEncoder& encoder) const"), out); + assertFalse(out.contains("Jsonize"), out); + } + + @Test + void subObjectHeader_forwardDeclaresCborValueOnly() { + // The forward declaration still names CborValue (the result payload type), matching C2J. + String out = render(cbor::writeShapeForwardDeclarations); + assertTrue(out.contains("class CborValue;"), out); + } + + // --- Source include/using sets must match C2J templates exactly. + + @Test + void requestSource_usesCborStreamingIncludesNotCborValue() { + // CborRequestSource.vm: only + ; NO + // (request payloads encode via the streaming CborEncoder, no CborValue DOM). + var inc = cbor.serdeIncludes(FileKind.REQUEST_SOURCE); + assertTrue(inc.contains("aws/crt/cbor/Cbor.h"), inc.toString()); + assertFalse(inc.contains("aws/core/utils/cbor/CborValue.h"), inc.toString()); + } + + @Test + void requestSource_usingsAreCborCryptoAndUtilsOnly() { + // CborRequestSource.vm usings: Aws::Crt::Cbor + Aws::Utils. NOT Aws::Crt / Aws::Utils::Cbor. + var usings = cbor.serdeUsings(FileKind.REQUEST_SOURCE); + assertTrue(usings.contains("Aws::Crt::Cbor"), usings.toString()); + assertTrue(usings.contains("Aws::Utils"), usings.toString()); + assertFalse(usings.contains("Aws::Crt"), usings.toString()); + assertFalse(usings.contains("Aws::Utils::Cbor"), usings.toString()); + } + + @Test + void subObjectSource_usingsAreCborCryptoAndUtilsOnly() { + // CborSubObjectSource.vm usings: Aws::Crt::Cbor + Aws::Utils only. + var usings = cbor.serdeUsings(FileKind.SUBOBJECT_SOURCE); + assertTrue(usings.contains("Aws::Crt::Cbor"), usings.toString()); + assertTrue(usings.contains("Aws::Utils"), usings.toString()); + assertFalse(usings.contains("Aws::Crt"), usings.toString()); + assertFalse(usings.contains("Aws::Utils::Cbor"), usings.toString()); + } + + @Test + void resultSerdeDecls_useCborValuePayload() { + String out = render(w -> cbor.writeResultSerdeDecls(w, "AWS_EXAMPLE_API", "DoThingResult")); + assertTrue(out.contains("Aws::AmazonWebServiceResult"), out); + } + + @Test + void requestImpls_noTargetHeaderAndEmptyBracesPayload() { + var req = reqWith(false, false); var model = modelWith(req); + String i = render(w -> cbor.writeRequestMethodImpls(w, "PingRequest", unitStructure(), opNoInput(), svcAthena(), model)); + assertFalse(i.contains("X-Amz-Target"), i); + } + + // hasRequest()==true (input structure present): CONTENT_TYPE emitted, real encoder (not "{}"). + @Test + void requestWithInput_emitsContentTypeAndEncoderPayload() { + var req = reqWith(false, false); var model = modelWith(req); + var op = opWithInput(req); + String i = render(w -> cbor.writeRequestMethodImpls(w, "DoThingRequest", req, op, svcAthena(), model)); + assertTrue(i.contains("Aws::Crt::Cbor::CborEncoder encoder;"), i); + assertTrue(i.contains("headers.emplace(Aws::Http::CONTENT_TYPE_HEADER, Aws::CBOR_CONTENT_TYPE);"), i); + assertTrue(i.contains("headers.emplace(Aws::Http::SMITHY_PROTOCOL_HEADER, Aws::RPC_V2_CBOR);"), i); + assertTrue(i.contains("headers.emplace(Aws::Http::ACCEPT_HEADER, Aws::CBOR_CONTENT_TYPE);"), i); + } + + // hasRequest()==false (input targets smithy.api#Unit): SerializePayload returns {}, NO CONTENT_TYPE. + @Test + void noInputRequest_returnsEmptyBracesAndOmitsContentType() { + var op = opNoInput(); + var unit = unitStructure(); + var model = modelWith(unit); + String i = render(w -> cbor.writeRequestMethodImpls(w, "PingRequest", unit, op, svcAthena(), model)); + assertTrue(i.contains("Aws::String PingRequest::SerializePayload() const { return {}; }"), i); + assertFalse(i.contains("CONTENT_TYPE_HEADER"), i); + assertTrue(i.contains("headers.emplace(Aws::Http::SMITHY_PROTOCOL_HEADER, Aws::RPC_V2_CBOR);"), i); + assertTrue(i.contains("headers.emplace(Aws::Http::ACCEPT_HEADER, Aws::CBOR_CONTENT_TYPE);"), i); + } +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/FileKindTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/FileKindTest.java new file mode 100644 index 000000000000..71c4d153a9c4 --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/FileKindTest.java @@ -0,0 +1,23 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class FileKindTest { + @Test + void hasAllEightFileKinds() { + assertEquals(8, FileKind.values().length); + // Referencing each constant compiles only if it exists. + FileKind[] all = { + FileKind.SUBOBJECT_HEADER, FileKind.RESULT_HEADER, FileKind.SUBOBJECT_SOURCE, + FileKind.REQUEST_SOURCE, FileKind.RESULT_SOURCE, FileKind.STREAMING_RESULT_SOURCE, + FileKind.EVENT_HANDLER_SOURCE, FileKind.INITIAL_RESPONSE_SOURCE + }; + assertEquals(8, all.length); + } +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraitsTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraitsTest.java index 89b527be037e..7f4281bf8f2a 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraitsTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraitsTest.java @@ -21,18 +21,47 @@ private static String render(java.util.function.Consumer body) { } private final ProtocolTraits json = new JsonProtocolTraits(Protocol.JSON); - private final ProtocolTraits cbor = new JsonProtocolTraits(Protocol.CBOR); + private final ProtocolTraits restJson = new JsonProtocolTraits(Protocol.REST_JSON); + + private static software.amazon.smithy.model.shapes.StructureShape reqWith(boolean header, boolean query) { + software.amazon.smithy.model.shapes.StructureShape.Builder b = + software.amazon.smithy.model.shapes.StructureShape.builder().id("com.example#DoThingRequest"); + if (header) { + b.addMember(software.amazon.smithy.model.shapes.MemberShape.builder() + .id("com.example#DoThingRequest$h").target("com.example#Str") + .addTrait(new software.amazon.smithy.model.traits.HttpHeaderTrait("X-H")).build()); + } + if (query) { + b.addMember(software.amazon.smithy.model.shapes.MemberShape.builder() + .id("com.example#DoThingRequest$q").target("com.example#Str") + .addTrait(new software.amazon.smithy.model.traits.HttpQueryTrait("q")).build()); + } + return b.build(); + } + private static software.amazon.smithy.model.shapes.OperationShape opDoThing() { + return software.amazon.smithy.model.shapes.OperationShape.builder().id("com.example#DoThing").build(); + } + private static software.amazon.smithy.model.shapes.ServiceShape svcAthena() { + return software.amazon.smithy.model.shapes.ServiceShape.builder() + .id("com.example#AmazonAthena").version("2017-05-18").build(); + } + private static software.amazon.smithy.model.Model modelWith( + software.amazon.smithy.model.shapes.StructureShape req) { + return software.amazon.smithy.model.Model.builder() + .addShapes(software.amazon.smithy.model.shapes.StringShape.builder().id("com.example#Str").build(), req) + .build(); + } @Test void reportsItsOwnProtocolIdentity() { assertEquals(Protocol.JSON, json.protocol()); - assertEquals(Protocol.CBOR, cbor.protocol()); + assertEquals(Protocol.REST_JSON, restJson.protocol()); } @Test void serdeNamespace_isJsonUtils() { assertEquals("Aws::Utils::Json", json.serdeNamespace()); - assertEquals("Aws::Utils::Json", cbor.serdeNamespace()); + assertEquals("Aws::Utils::Json", restJson.serdeNamespace()); } @Test @@ -94,7 +123,8 @@ void resultSerdeDecls_useJsonValuePayload() { @Test void resultSerdeImpls_useJsonValuePayload() { - String out = render(w -> json.writeResultSerdeImpls(w, "DoThingResult")); + var req = reqWith(false, false); var model = modelWith(req); + String out = render(w -> json.writeResultSerdeImpls(w, "DoThingResult", req, model, "Example")); assertTrue(out.contains("DoThingResult::DoThingResult(const " + "Aws::AmazonWebServiceResult& result) {"), out); assertTrue(out.contains("*this = result;"), out); @@ -105,11 +135,50 @@ void resultSerdeImpls_useJsonValuePayload() { @Test void serdeIncludeAndUsings_areJsonFlavored() { - assertTrue(render(json::writeSerdeInclude) - .contains("#include ")); - String usings = render(json::writeSerdeUsingDeclarations); - assertTrue(usings.contains("using namespace Aws::Utils::Json;"), usings); - assertTrue(usings.contains("using namespace Aws::Utils;"), usings); + assertTrue(json.serdeIncludes(FileKind.SUBOBJECT_SOURCE) + .contains("aws/core/utils/json/JsonSerializer.h")); + var usings = json.serdeUsings(FileKind.SUBOBJECT_SOURCE); + assertTrue(usings.contains("Aws::Utils::Json"), usings.toString()); + assertTrue(usings.contains("Aws::Utils"), usings.toString()); + } + + @Test + void awsJson_alwaysDeclaresTargetHeaderAndSerializePayload() { + var req = reqWith(false, false); var model = modelWith(req); + String d = render(w -> json.writeRequestMethodDecls(w, "AWS_EX_API", req, opDoThing(), model)); + assertTrue(d.contains("AWS_EX_API Aws::String SerializePayload() const override;"), d); + assertTrue(d.contains("Aws::Http::HeaderValueCollection GetRequestSpecificHeaders() const override;"), d); + assertFalse(d.contains("DumpBodyToUrl"), d); + String i = render(w -> json.writeRequestMethodImpls(w, "DoThingRequest", req, opDoThing(), svcAthena(), model)); + assertTrue(i.contains("Aws::String DoThingRequest::SerializePayload() const { return \"{}\"; }"), i); + assertTrue(i.contains("headers.insert(Aws::Http::HeaderValuePair(\"X-Amz-Target\", \"AmazonAthena.DoThing\"));"), i); + } + + @Test + void restJson_noBindings_hasNoHeadersMethodAndReturnsEmptyBraces() { + var req = reqWith(false, false); var model = modelWith(req); + String d = render(w -> restJson.writeRequestMethodDecls(w, "AWS_EX_API", req, opDoThing(), model)); + assertTrue(d.contains("SerializePayload() const override;"), d); + assertFalse(d.contains("GetRequestSpecificHeaders"), d); + String i = render(w -> restJson.writeRequestMethodImpls(w, "DoThingRequest", req, opDoThing(), svcAthena(), model)); + assertTrue(i.contains("Aws::String DoThingRequest::SerializePayload() const { return {}; }"), i); + assertFalse(i.contains("X-Amz-Target"), i); + } + + @Test + void restJson_withHeaderMember_emitsHeadersMethodWithoutTarget() { + var req = reqWith(true, false); var model = modelWith(req); + String d = render(w -> restJson.writeRequestMethodDecls(w, "AWS_EX_API", req, opDoThing(), model)); + assertTrue(d.contains("GetRequestSpecificHeaders() const override;"), d); + String i = render(w -> restJson.writeRequestMethodImpls(w, "DoThingRequest", req, opDoThing(), svcAthena(), model)); + assertFalse(i.contains("X-Amz-Target"), i); + } + + @Test + void json_withQueryMember_emitsAddQueryStringParameters() { + var req = reqWith(false, true); var model = modelWith(req); + String d = render(w -> json.writeRequestMethodDecls(w, "AWS_EX_API", req, opDoThing(), model)); + assertTrue(d.contains("void AddQueryStringParameters(Aws::Http::URI& uri) const override;"), d); } @Test diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsIncludeSetTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsIncludeSetTest.java new file mode 100644 index 000000000000..f0555fd61808 --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsIncludeSetTest.java @@ -0,0 +1,167 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol; + +import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ProtocolTraitsIncludeSetTest { + + @Test + void json_resultSource_includesMatchOldResultHook() { + ProtocolTraits json = new JsonProtocolTraits(Protocol.JSON); + List inc = json.serdeIncludes(FileKind.RESULT_SOURCE); + assertTrue(inc.contains("aws/core/utils/json/JsonSerializer.h"), inc.toString()); + assertTrue(inc.contains("aws/core/utils/UnreferencedParam.h"), inc.toString()); + assertTrue(inc.contains("aws/core/utils/memory/stl/AWSStringStream.h"), inc.toString()); + } + + @Test + void queryXml_requestSource_usesStringStreamNotXmlSerializer() { + ProtocolTraits q = new QueryXmlProtocolTraits(Protocol.QUERY_XML); + List inc = q.serdeIncludes(FileKind.REQUEST_SOURCE); + assertTrue(inc.contains("aws/core/utils/StringUtils.h"), inc.toString()); + assertTrue(inc.contains("aws/core/utils/memory/stl/AWSStringStream.h"), inc.toString()); + assertTrue(inc.stream().noneMatch(s -> s.contains("XmlSerializer")), inc.toString()); + assertTrue(inc.stream().noneMatch(s -> s.equals("utility")), inc.toString()); + } + + @Test + void queryXml_resultSource_usingsIncludeLogging() { + ProtocolTraits q = new QueryXmlProtocolTraits(Protocol.QUERY_XML); + List usings = q.serdeUsings(FileKind.RESULT_SOURCE); + assertEquals(List.of("Aws::Utils::Xml", "Aws::Utils::Logging", "Aws::Utils"), usings); + } + + @Test + void queryXml_subobjectHeader_hasStreamFwd() { + ProtocolTraits q = new QueryXmlProtocolTraits(Protocol.QUERY_XML); + assertTrue(q.serdeIncludes(FileKind.SUBOBJECT_HEADER) + .contains("aws/core/utils/memory/stl/AWSStreamFwd.h"), + q.serdeIncludes(FileKind.SUBOBJECT_HEADER).toString()); + } + + @Test + void restXml_requestSource_hasUtilityAndXmlSerializer() { + ProtocolTraits x = new RestXmlProtocolTraits(); + List inc = x.serdeIncludes(FileKind.REQUEST_SOURCE); + assertTrue(inc.contains("aws/core/utils/xml/XmlSerializer.h"), inc.toString()); + assertTrue(inc.contains("utility"), inc.toString()); + } + + @Test + void cbor_resultSource_hasCborAndUnreferencedAndStringStream() { + ProtocolTraits c = new CborProtocolTraits(); + List inc = c.serdeIncludes(FileKind.RESULT_SOURCE); + assertTrue(inc.contains("aws/crt/cbor/Cbor.h"), inc.toString()); + assertTrue(inc.contains("aws/core/utils/cbor/CborValue.h"), inc.toString()); + assertTrue(inc.contains("aws/core/utils/UnreferencedParam.h"), inc.toString()); + assertTrue(inc.contains("aws/core/utils/memory/stl/AWSStringStream.h"), inc.toString()); + } + + @Test + void eventHandler_usings_isSerdeNamespaceOnly() { + assertEquals(List.of("Aws::Utils::Json"), + new JsonProtocolTraits(Protocol.JSON).serdeUsings(FileKind.EVENT_HANDLER_SOURCE)); + assertEquals(List.of("Aws::Utils::Cbor"), + new CborProtocolTraits().serdeUsings(FileKind.EVENT_HANDLER_SOURCE)); + } + + @Test + void initialResponseSource_excludesStringStream() { + List json = new JsonProtocolTraits(Protocol.JSON).serdeIncludes(FileKind.INITIAL_RESPONSE_SOURCE); + assertTrue(json.contains("aws/core/utils/json/JsonSerializer.h"), json.toString()); + assertTrue(json.contains("aws/core/utils/UnreferencedParam.h"), json.toString()); + assertTrue(json.stream().noneMatch(s -> s.equals("aws/core/utils/memory/stl/AWSStringStream.h")), json.toString()); + + List cbor = new CborProtocolTraits().serdeIncludes(FileKind.INITIAL_RESPONSE_SOURCE); + assertTrue(cbor.contains("aws/crt/cbor/Cbor.h"), cbor.toString()); + assertTrue(cbor.contains("aws/core/utils/cbor/CborValue.h"), cbor.toString()); + assertTrue(cbor.contains("aws/core/utils/UnreferencedParam.h"), cbor.toString()); + assertTrue(cbor.stream().noneMatch(s -> s.equals("aws/core/utils/memory/stl/AWSStringStream.h")), cbor.toString()); + } + + @Test + void xmlInitialResponseSource_excludesResultOnlyIncludes() { + List restXml = new RestXmlProtocolTraits().serdeIncludes(FileKind.INITIAL_RESPONSE_SOURCE); + assertTrue(restXml.contains("aws/core/utils/xml/XmlSerializer.h"), restXml.toString()); + assertTrue(restXml.contains("aws/core/utils/UnreferencedParam.h"), restXml.toString()); + assertTrue(restXml.stream().noneMatch(s -> s.equals("aws/core/utils/memory/stl/AWSStringStream.h")), + restXml.toString()); + + List queryXml = + new QueryXmlProtocolTraits(Protocol.QUERY_XML).serdeIncludes(FileKind.INITIAL_RESPONSE_SOURCE); + assertTrue(queryXml.contains("aws/core/utils/UnreferencedParam.h"), queryXml.toString()); + assertTrue(queryXml.stream().noneMatch(s -> s.equals("aws/core/utils/memory/stl/AWSStringStream.h")), + queryXml.toString()); + assertTrue(queryXml.stream().noneMatch(s -> s.equals("aws/core/utils/logging/LogMacros.h")), + queryXml.toString()); + + List restXmlUsings = new RestXmlProtocolTraits().serdeUsings(FileKind.INITIAL_RESPONSE_SOURCE); + assertTrue(restXmlUsings.stream().noneMatch(s -> s.equals("Aws::Utils::Logging")), restXmlUsings.toString()); + + List queryXmlUsings = + new QueryXmlProtocolTraits(Protocol.QUERY_XML).serdeUsings(FileKind.INITIAL_RESPONSE_SOURCE); + assertTrue(queryXmlUsings.stream().noneMatch(s -> s.equals("Aws::Utils::Logging")), queryXmlUsings.toString()); + } + + @Test + void streamingResult_serdeIncludes_isEmpty() { + assertTrue(new RestXmlProtocolTraits().serdeIncludes(FileKind.STREAMING_RESULT_SOURCE).isEmpty()); + } + + @Test + void subObjectHeader_hasNoSerializerInclude() { + List json = new JsonProtocolTraits(Protocol.JSON).serdeIncludes(FileKind.SUBOBJECT_HEADER); + assertTrue(json.isEmpty(), json.toString()); + assertTrue(json.stream().noneMatch(s -> s.equals("aws/core/utils/json/JsonSerializer.h")), json.toString()); + + List restXml = new RestXmlProtocolTraits().serdeIncludes(FileKind.SUBOBJECT_HEADER); + assertTrue(restXml.stream().noneMatch(s -> s.equals("aws/core/utils/xml/XmlSerializer.h")), restXml.toString()); + + // CBOR is the exception: its sub-object header signatures reference Aws::Crt::Cbor::CborDecoder + // / CborEncoder directly, so CborSubObjectHeader.vm hard-includes . + List cbor = new CborProtocolTraits().serdeIncludes(FileKind.SUBOBJECT_HEADER); + assertTrue(cbor.contains("aws/crt/cbor/Cbor.h"), cbor.toString()); + + List queryXml = + new QueryXmlProtocolTraits(Protocol.QUERY_XML).serdeIncludes(FileKind.SUBOBJECT_HEADER); + assertTrue(queryXml.contains("aws/core/utils/memory/stl/AWSStreamFwd.h"), queryXml.toString()); + } + + @Test + void resultHeader_onlyCborHardIncludesCborHeader() { + // CborResultHeader.vm hard-includes ; JSON/XML/Query result headers + // forward-declare their payload type and add no serde include. + assertTrue(new CborProtocolTraits().serdeIncludes(FileKind.RESULT_HEADER) + .contains("aws/crt/cbor/Cbor.h"), + new CborProtocolTraits().serdeIncludes(FileKind.RESULT_HEADER).toString()); + assertTrue(new JsonProtocolTraits(Protocol.JSON).serdeIncludes(FileKind.RESULT_HEADER).isEmpty()); + assertTrue(new RestXmlProtocolTraits().serdeIncludes(FileKind.RESULT_HEADER).isEmpty()); + assertTrue(new QueryXmlProtocolTraits(Protocol.QUERY_XML) + .serdeIncludes(FileKind.RESULT_HEADER).isEmpty()); + } + + @Test + void serdeSwitches_throwOnUnhandledFileKind() { + // FileKinds never passed to serdeUsings must fail fast rather than default silently. + assertThrows(UnsupportedOperationException.class, + () -> new JsonProtocolTraits(Protocol.JSON).serdeUsings(FileKind.SUBOBJECT_HEADER)); + assertThrows(UnsupportedOperationException.class, + () -> new JsonProtocolTraits(Protocol.JSON).serdeUsings(FileKind.STREAMING_RESULT_SOURCE)); + assertThrows(UnsupportedOperationException.class, + () -> new RestXmlProtocolTraits().serdeUsings(FileKind.SUBOBJECT_HEADER)); + assertThrows(UnsupportedOperationException.class, + () -> new CborProtocolTraits().serdeUsings(FileKind.STREAMING_RESULT_SOURCE)); + assertThrows(UnsupportedOperationException.class, + () -> new QueryXmlProtocolTraits(Protocol.QUERY_XML).serdeUsings(FileKind.SUBOBJECT_HEADER)); + } +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsSerdeTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsSerdeTest.java index b6100b4ca776..8a8964a9ad09 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsSerdeTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsSerdeTest.java @@ -54,6 +54,46 @@ void errorPayloadParse_isProtocolAgnostic(Protocol p) { assertFalse(out.contains("XmlNode"), "Should not emit XML tokens for " + p + ": " + out); } + @Test + void defaultPredicates_detectHeaderAndQueryMembers() { + software.amazon.smithy.model.shapes.StringShape str = + software.amazon.smithy.model.shapes.StringShape.builder().id("com.example#Str").build(); + software.amazon.smithy.model.shapes.MemberShape headerMember = + software.amazon.smithy.model.shapes.MemberShape.builder() + .id("com.example#Req$h").target("com.example#Str") + .addTrait(new software.amazon.smithy.model.traits.HttpHeaderTrait("X-Thing")).build(); + software.amazon.smithy.model.shapes.MemberShape queryMember = + software.amazon.smithy.model.shapes.MemberShape.builder() + .id("com.example#Req$q").target("com.example#Str") + .addTrait(new software.amazon.smithy.model.traits.HttpQueryTrait("thing")).build(); + software.amazon.smithy.model.shapes.StructureShape req = + software.amazon.smithy.model.shapes.StructureShape.builder() + .id("com.example#Req").addMember(headerMember).addMember(queryMember).build(); + software.amazon.smithy.model.Model model = + software.amazon.smithy.model.Model.builder().addShapes(str, req).build(); + + ProtocolTraits t = ProtocolResolver.traitsFor(ProtocolResolver.Protocol.JSON); + assertTrue(t.requestHasHeaderMembers(req, model)); + assertTrue(t.requestHasQueryStringMembers(req, model)); + } + + @Test + void defaultPredicates_falseWhenNoBindings() { + software.amazon.smithy.model.shapes.StringShape str = + software.amazon.smithy.model.shapes.StringShape.builder().id("com.example#S").build(); + software.amazon.smithy.model.shapes.StructureShape req = + software.amazon.smithy.model.shapes.StructureShape.builder() + .id("com.example#R") + .addMember(software.amazon.smithy.model.shapes.MemberShape.builder() + .id("com.example#R$plain").target("com.example#S").build()) + .build(); + software.amazon.smithy.model.Model model = + software.amazon.smithy.model.Model.builder().addShapes(str, req).build(); + ProtocolTraits t = ProtocolResolver.traitsFor(ProtocolResolver.Protocol.REST_XML); + assertFalse(t.requestHasHeaderMembers(req, model)); + assertFalse(t.requestHasQueryStringMembers(req, model)); + } + /** The JSON serde method bodies are empty stubs pending schema-based serde. */ @Test void jsonSerdeMethodImpls_emitEmptyBodies() { diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsStreamingPayloadTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsStreamingPayloadTest.java new file mode 100644 index 000000000000..589b6cdf29e3 --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsStreamingPayloadTest.java @@ -0,0 +1,112 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol; + +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; +import org.junit.jupiter.api.Test; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.BlobShape; +import software.amazon.smithy.model.shapes.OperationShape; +import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.model.shapes.StringShape; +import software.amazon.smithy.model.shapes.StructureShape; +import software.amazon.smithy.model.traits.HttpPayloadTrait; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * C2J gates {@code SerializePayload()} on {@code !hasStreamMembers()} in the single shared + * {@code RequestHeader.vm}, so the rule is protocol-agnostic: no protocol emits SerializePayload + * for a request with a raw streaming {@code @httpPayload} member. These tests pin that every + * {@link ProtocolTraits} implementation honours it (and still emits SerializePayload for a plain + * request). + */ +class ProtocolTraitsStreamingPayloadTest { + + private static List allTraits() { + return List.of( + new JsonProtocolTraits(Protocol.JSON), + new JsonProtocolTraits(Protocol.REST_JSON), + new RestXmlProtocolTraits(), + new QueryXmlProtocolTraits(Protocol.QUERY_XML), + new QueryXmlProtocolTraits(Protocol.EC2), + new CborProtocolTraits()); + } + + /** An operation whose input binds an @httpPayload blob (raw streaming payload). */ + private static Model streamingPayloadModel() { + BlobShape body = BlobShape.builder().id("com.example#Body").build(); + StructureShape input = StructureShape.builder() + .id("com.example#DoThingRequest") + .addMember(software.amazon.smithy.model.shapes.MemberShape.builder() + .id("com.example#DoThingRequest$body").target(body.getId()) + .addTrait(new HttpPayloadTrait()).build()) + .build(); + return modelWith(body, input); + } + + /** An operation whose input is a plain structure (no streaming payload). */ + private static Model plainModel() { + StringShape str = StringShape.builder().id("com.example#Str").build(); + StructureShape input = StructureShape.builder() + .id("com.example#DoThingRequest").addMember("name", str.getId()).build(); + return modelWith(str, input); + } + + private static Model modelWith(software.amazon.smithy.model.shapes.Shape extra, StructureShape input) { + OperationShape op = OperationShape.builder() + .id("com.example#DoThing").input(input.getId()).build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#Example").version("2024-01-01").addOperation(op.getId()).build(); + return Model.builder().addShapes(extra, input, op, service).build(); + } + + private static OperationShape op(Model model) { + return model.expectShape(software.amazon.smithy.model.shapes.ShapeId.from("com.example#DoThing"), + OperationShape.class); + } + + private static StructureShape req(Model model) { + return model.expectShape(software.amazon.smithy.model.shapes.ShapeId.from("com.example#DoThingRequest"), + StructureShape.class); + } + + private static String renderDecls(ProtocolTraits traits, Model model) { + CppWriter writer = new CppWriter(); + writer.indent(); // Query/EC2 decls open with a dedent for the protected: sandwich + traits.writeRequestMethodDecls(writer, "AWS_EX_API", req(model), op(model), model); + return writer.toString(); + } + + @Test + void allProtocols_omitSerializePayload_forRawStreamingPayloadRequest() { + Model model = streamingPayloadModel(); + for (ProtocolTraits traits : allTraits()) { + assertFalse(traits.emitsSerializePayload(op(model), model), + traits.getClass().getSimpleName() + "/" + traits.protocol() + + " must report emitsSerializePayload=false for a streaming-payload request"); + assertFalse(renderDecls(traits, model).contains("SerializePayload"), + traits.getClass().getSimpleName() + "/" + traits.protocol() + + " must not emit a SerializePayload decl for a streaming-payload request"); + } + } + + @Test + void allProtocols_emitSerializePayload_forPlainRequest() { + Model model = plainModel(); + for (ProtocolTraits traits : allTraits()) { + assertTrue(traits.emitsSerializePayload(op(model), model), + traits.getClass().getSimpleName() + "/" + traits.protocol() + + " must report emitsSerializePayload=true for a plain request"); + assertTrue(renderDecls(traits, model).contains("SerializePayload"), + traits.getClass().getSimpleName() + "/" + traits.protocol() + + " must emit a SerializePayload decl for a plain request"); + } + } +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/XmlProtocolTraitsTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/XmlProtocolTraitsTest.java index be397d8dad81..dc04e36ef508 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/XmlProtocolTraitsTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/XmlProtocolTraitsTest.java @@ -23,10 +23,52 @@ private static String render(java.util.function.Consumer body) { return writer.toString(); } + /** + * Renders inside a simulated class body (indent level 1), matching how request-method + * declarations are emitted by {@code RequestRenderer}. Query/EC2 decls open with a + * {@code dedent()} for the {@code protected:} sandwich, which requires a non-zero + * starting indent. + */ + private static String renderInClassBody(java.util.function.Consumer body) { + CppWriter writer = new CppWriter(); + writer.indent(); + body.accept(writer); + return writer.toString(); + } + private final ProtocolTraits restXml = new RestXmlProtocolTraits(); private final ProtocolTraits queryXml = new QueryXmlProtocolTraits(Protocol.QUERY_XML); private final ProtocolTraits ec2 = new QueryXmlProtocolTraits(Protocol.EC2); + private static software.amazon.smithy.model.shapes.StructureShape reqWith(boolean header, boolean query) { + software.amazon.smithy.model.shapes.StructureShape.Builder b = + software.amazon.smithy.model.shapes.StructureShape.builder().id("com.example#DoThingRequest"); + if (header) { + b.addMember(software.amazon.smithy.model.shapes.MemberShape.builder() + .id("com.example#DoThingRequest$h").target("com.example#Str") + .addTrait(new software.amazon.smithy.model.traits.HttpHeaderTrait("X-H")).build()); + } + if (query) { + b.addMember(software.amazon.smithy.model.shapes.MemberShape.builder() + .id("com.example#DoThingRequest$q").target("com.example#Str") + .addTrait(new software.amazon.smithy.model.traits.HttpQueryTrait("q")).build()); + } + return b.build(); + } + private static software.amazon.smithy.model.shapes.OperationShape opDoThing() { + return software.amazon.smithy.model.shapes.OperationShape.builder().id("com.example#DoThing").build(); + } + private static software.amazon.smithy.model.shapes.ServiceShape svcAthena() { + return software.amazon.smithy.model.shapes.ServiceShape.builder() + .id("com.example#AmazonAthena").version("2017-05-18").build(); + } + private static software.amazon.smithy.model.Model modelWith( + software.amazon.smithy.model.shapes.StructureShape req) { + return software.amazon.smithy.model.Model.builder() + .addShapes(software.amazon.smithy.model.shapes.StringShape.builder().id("com.example#Str").build(), req) + .build(); + } + // ---------- identity ---------- @Test @@ -133,12 +175,12 @@ void allXmlTraits_shareForwardDeclarationsIncludeAndUsings() { assertFalse(resultFwd.contains("class XmlNode;"), "Result headers declare the document type, not the node type: " + resultFwd); - assertTrue(render(traits::writeSerdeInclude) - .contains("#include ")); + assertTrue(traits.serdeIncludes(FileKind.SUBOBJECT_SOURCE) + .contains("aws/core/utils/xml/XmlSerializer.h")); - String usings = render(traits::writeSerdeUsingDeclarations); - assertTrue(usings.contains("using namespace Aws::Utils::Xml;"), usings); - assertTrue(usings.contains("using namespace Aws::Utils;"), usings); + var usings = traits.serdeUsings(FileKind.SUBOBJECT_SOURCE); + assertTrue(usings.contains("Aws::Utils::Xml"), usings.toString()); + assertTrue(usings.contains("Aws::Utils"), usings.toString()); } } @@ -151,11 +193,100 @@ void allXmlTraits_useXmlDocumentForResults() { assertTrue(decls.contains("AWS_EXAMPLE_API DoThingResult& operator=(const " + "Aws::AmazonWebServiceResult& result);"), decls); - String impls = render(w -> traits.writeResultSerdeImpls(w, "DoThingResult")); + var req = reqWith(false, false); var model = modelWith(req); + String impls = render(w -> traits.writeResultSerdeImpls(w, "DoThingResult", req, model, "Example")); assertTrue(impls.contains("DoThingResult::DoThingResult(const " + "Aws::AmazonWebServiceResult& result) {"), impls); assertTrue(impls.contains("DoThingResult& DoThingResult::operator=(const " + "Aws::AmazonWebServiceResult& result) {"), impls); } } + + // ---------- REST_XML request contract (Axis-1 gating) ---------- + + @Test + void restXml_noBindings_onlySerializePayload() { + var req = reqWith(false, false); var model = modelWith(req); + ProtocolTraits xml = new RestXmlProtocolTraits(); + String d = render(w -> xml.writeRequestMethodDecls(w, "AWS_EX_API", req, opDoThing(), model)); + assertTrue(d.contains("Aws::String SerializePayload() const override;"), d); + assertFalse(d.contains("GetRequestSpecificHeaders"), d); + assertFalse(d.contains("DumpBodyToUrl"), d); + assertFalse(d.contains("AddQueryStringParameters"), d); + String i = render(w -> xml.writeRequestMethodImpls(w, "DoThingRequest", req, opDoThing(), svcAthena(), model)); + assertTrue(i.contains("Aws::String DoThingRequest::SerializePayload() const { return {}; }"), i); + } + + @Test + void restXml_withHeaderMember_emitsHeadersWithoutTarget() { + var req = reqWith(true, false); var model = modelWith(req); + ProtocolTraits xml = new RestXmlProtocolTraits(); + String d = render(w -> xml.writeRequestMethodDecls(w, "AWS_EX_API", req, opDoThing(), model)); + assertTrue(d.contains("GetRequestSpecificHeaders() const override;"), d); + String i = render(w -> xml.writeRequestMethodImpls(w, "DoThingRequest", req, opDoThing(), svcAthena(), model)); + assertFalse(i.contains("X-Amz-Target"), i); + } + + @Test + void restXml_withQueryMember_emitsAddQueryStringParameters() { + var req = reqWith(false, true); var model = modelWith(req); + ProtocolTraits xml = new RestXmlProtocolTraits(); + String d = render(w -> xml.writeRequestMethodDecls(w, "AWS_EX_API", req, opDoThing(), model)); + assertTrue(d.contains("void AddQueryStringParameters(Aws::Http::URI& uri) const override;"), d); + } + + // ---------- Query/EC2 request contract (Axis-1 gating + protected DumpBodyToUrl) ---------- + + @Test + void queryXml_serializePayloadAndProtectedDumpBodyToUrl() { + var req = reqWith(false, false); var model = modelWith(req); + ProtocolTraits q = new QueryXmlProtocolTraits(Protocol.QUERY_XML); + String d = renderInClassBody(w -> q.writeRequestMethodDecls(w, "AWS_EX_API", req, opDoThing(), model)); + assertTrue(d.contains("Aws::String SerializePayload() const override;"), d); + assertTrue(d.contains("void DumpBodyToUrl(Aws::Http::URI& uri) const override;"), d); + assertTrue(d.contains("protected:"), d); + assertTrue(d.contains("public:"), d); + assertFalse(d.contains("GetRequestSpecificHeaders"), d); + String i = render(w -> q.writeRequestMethodImpls(w, "DoThingRequest", req, opDoThing(), svcAthena(), model)); + assertTrue(i.contains("Aws::String DoThingRequest::SerializePayload() const { return {}; }"), i); + assertTrue(i.contains("void DoThingRequest::DumpBodyToUrl(Aws::Http::URI& uri) const { uri.SetQueryString(SerializePayload()); }"), i); + } + + @Test + void queryXml_withHeaderMember_alsoEmitsHeaders_andStillDumpBodyToUrl() { + var req = reqWith(true, false); var model = modelWith(req); + ProtocolTraits q = new QueryXmlProtocolTraits(Protocol.QUERY_XML); + String d = renderInClassBody(w -> q.writeRequestMethodDecls(w, "AWS_EX_API", req, opDoThing(), model)); + assertTrue(d.contains("GetRequestSpecificHeaders() const override;"), d); + assertTrue(d.contains("DumpBodyToUrl"), d); + } + + // ---------- Query/EC2 result ResponseMetadata / requestId extraction ---------- + + @Test + void queryResult_extractsResponseMetadata() { + var req = reqWith(false, false); var model = modelWith(req); + String out = render(w -> new QueryXmlProtocolTraits(Protocol.QUERY_XML) + .writeResultSerdeImpls(w, "GetThingResult", req, model, "IAM")); + assertTrue(out.contains("FirstChild(\"ResponseMetadata\")"), out); + assertTrue(out.contains("m_responseMetadata"), out); + } + + @Test + void queryResult_logTagIsFullyQualified() { + // C2J logs with the fully-qualified class name (Aws::::Model::). + var req = reqWith(false, false); var model = modelWith(req); + String out = render(w -> new QueryXmlProtocolTraits(Protocol.QUERY_XML) + .writeResultSerdeImpls(w, "GetThingResult", req, model, "IAM")); + assertTrue(out.contains("AWS_LOGSTREAM_DEBUG(\"Aws::IAM::Model::GetThingResult\""), out); + } + + @Test + void ec2Result_extractsRequestIdChild() { + var req = reqWith(false, false); var model = modelWith(req); + String out = render(w -> new QueryXmlProtocolTraits(Protocol.EC2) + .writeResultSerdeImpls(w, "GetThingResult", req, model, "IAM")); + assertTrue(out.contains("FirstChild(\"requestId\")"), out); + assertTrue(out.contains("SetRequestId"), out); + } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSetsTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSetsTest.java new file mode 100644 index 000000000000..043bd71d4b12 --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSetsTest.java @@ -0,0 +1,82 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; + +class IncludeSetsTest { + + @Test + void resultHeaderBase_withRequestId_hasAwsString() { + List inc = IncludeSets.resultHeaderBase("iam", "IAM", true); + assertTrue(inc.contains("aws/core/http/HttpResponse.h"), inc.toString()); + assertTrue(inc.contains("aws/iam/IAM_EXPORTS.h"), inc.toString()); + assertTrue(inc.contains("aws/core/utils/memory/stl/AWSString.h"), inc.toString()); + } + + @Test + void resultHeaderBase_withoutRequestId_omitsAwsString() { + List inc = IncludeSets.resultHeaderBase("iam", "IAM", false); + assertFalse(inc.contains("aws/core/utils/memory/stl/AWSString.h"), inc.toString()); + } + + @Test + void resultSourceBase_hasAwsResultAndStringUtilsAndSelfHeaderAndUtility() { + List inc = IncludeSets.resultSourceBase("iam", "GetRoleResult"); + assertEquals(List.of( + "aws/core/AmazonWebServiceResult.h", + "aws/core/utils/StringUtils.h", + "aws/iam/model/GetRoleResult.h", + "utility"), inc); + } + + @Test + void streamingResultSourceBase_hasStringStreamButNoSerdeHeader() { + List inc = IncludeSets.streamingResultSourceBase("s3", "GetObjectResult"); + assertTrue(inc.contains("aws/core/AmazonWebServiceResult.h"), inc.toString()); + assertTrue(inc.contains("aws/core/utils/memory/stl/AWSStringStream.h"), inc.toString()); + assertTrue(inc.contains("aws/s3/model/GetObjectResult.h"), inc.toString()); + assertTrue(inc.contains("utility"), inc.toString()); + } + + @Test + void requestSourceBase_hasSelfHeaderAndNoUtility() { + // is carried by the per-protocol serdeIncludes(REQUEST_SOURCE), not the base, + // so Query/EC2 (which must not emit ) are not forced to include it. + List inc = IncludeSets.requestSourceBase("iam", "CreateRoleRequest"); + assertTrue(inc.contains("aws/iam/model/CreateRoleRequest.h"), inc.toString()); + assertFalse(inc.contains("utility"), inc.toString()); + } + + @Test + void emit_dedupsAndSortsAndWrapsInAngleBrackets() { + com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter w = + new com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter(); + IncludeSets.emit(w, java.util.List.of("b/z.h", "a/a.h", "b/z.h")); + String out = w.toString(); + assertTrue(out.contains("#include "), out); + assertTrue(out.contains("#include "), out); + // dedup: only one occurrence of b/z.h + assertEquals(out.indexOf("b/z.h"), out.lastIndexOf("b/z.h"), out); + // sorted: a/a.h before b/z.h + assertTrue(out.indexOf("a/a.h") < out.indexOf("b/z.h"), out); + } + + @Test + void emitUsings_preservesOrder() { + com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter w = + new com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter(); + IncludeSets.emitUsings(w, java.util.List.of("Aws::Utils::Xml", "Aws::Utils")); + String out = w.toString(); + assertTrue(out.indexOf("using namespace Aws::Utils::Xml;") + < out.indexOf("using namespace Aws::Utils;"), out); + } +} From ea233b603eaa87ca61d3e2254199c58715fba9e9 Mon Sep 17 00:00:00 2001 From: sbaluja Date: Tue, 11 Aug 2026 15:08:09 -0400 Subject: [PATCH 02/19] Refactor code cleanup Remove now-dead decapitalize wrapper in MemberRenderer (#0000) Final cleanup sweep: dead code, include + fieldName consolidation (#0000) Fail fast on missing streaming payload member in ResultRenderer (#0000) Clean up inline qualified names and helpers in RequestRenderer (#0000) Move protocol-invariant request binding queries out of ProtocolTraits (#0000) Replace MemberRenderer overload ladder with MemberOptions (#0000) Extract Aws::Model namespace scaffold into ModelFile helper (#0000) Introduce RenderContext to unify model renderer construction (#0000) Centralize header include-bracket policy in IncludeSets (#0000) Extract shared requestId accessor rendering in ResultRenderer (#0000) Add CppWriter.withNamespace scoped-nesting helper (#0000) Consolidate C++ identifier helpers into CppNames (#0000) --- .../generators/CppWriter.java | 12 + .../generators/model/CppNames.java | 30 +++ .../generators/model/MemberOptions.java | 29 +++ .../generators/model/MemberRenderer.java | 76 ++++--- .../generators/model/ModelCodegenPlugin.java | 2 +- .../generators/model/ModelGenerator.java | 40 +--- .../generators/model/RenderContext.java | 29 +++ .../generators/model/ShapeClassifier.java | 13 +- .../model/protocol/CborProtocolTraits.java | 8 +- .../model/protocol/JsonProtocolTraits.java | 12 +- .../model/protocol/ProtocolTraits.java | 41 +--- .../protocol/QueryXmlProtocolTraits.java | 12 +- .../model/protocol/RequestBindings.java | 54 +++++ .../model/protocol/RestXmlProtocolTraits.java | 12 +- .../model/renderers/EnumShapeRenderer.java | 18 +- .../model/renderers/EventStreamRenderer.java | 209 +++++++----------- .../model/renderers/IncludeSets.java | 16 ++ .../generators/model/renderers/ModelFile.java | 24 ++ .../OutgoingEventStreamRenderer.java | 58 ++--- .../model/renderers/RequestRenderer.java | 192 ++++++++-------- .../model/renderers/ResultRenderer.java | 190 ++++++---------- .../model/renderers/SubObjectRenderer.java | 83 +++---- .../model/transforms/GlobalTransforms.java | 5 + .../generators/CppWriterTest.java | 24 ++ .../generators/model/CppNamesTest.java | 30 +++ .../model/EventStreamRendererTest.java | 5 +- .../generators/model/MemberRendererTest.java | 42 ++++ .../OutgoingEventStreamRendererTest.java | 6 +- .../ProtocolTraitsCharacterizationTest.java | 12 +- .../generators/model/RequestRendererTest.java | 13 +- .../generators/model/ResultRendererTest.java | 13 +- .../generators/model/ShapeClassifierTest.java | 1 - .../model/SubObjectRendererTest.java | 6 +- .../protocol/ProtocolTraitsSerdeTest.java | 8 +- .../ProtocolTraitsStreamingPayloadTest.java | 4 +- .../model/protocol/RequestBindingsTest.java | 45 ++++ .../model/renderers/IncludeSetsTest.java | 13 ++ .../model/renderers/ModelFileTest.java | 29 +++ 38 files changed, 799 insertions(+), 617 deletions(-) create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppNames.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberOptions.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RenderContext.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RequestBindings.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ModelFile.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriterTest.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppNamesTest.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RequestBindingsTest.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ModelFileTest.java diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java index 6ddbed5c14b4..67d2fa892945 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java @@ -57,4 +57,16 @@ public CppWriter writeNamespaceClose(String namespace) { closeBlock("} // namespace $L", namespace); return this; } + + /** + * Opens {@code namespace}, runs {@code body}, then closes it — so the open and + * close can never drift out of sync. Equivalent to + * {@code writeNamespaceOpen(namespace); body.run(); writeNamespaceClose(namespace);} + */ + public CppWriter withNamespace(String namespace, Runnable body) { + writeNamespaceOpen(namespace); + body.run(); + writeNamespaceClose(namespace); + return this; + } } \ No newline at end of file diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppNames.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppNames.java new file mode 100644 index 000000000000..e41c59341a73 --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppNames.java @@ -0,0 +1,30 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model; + +/** + * Pure C++ identifier helpers shared by the model renderers. Centralizes the + * capitalize / decapitalize / field-name convention so it lives in one place + * rather than being copied privately into each renderer. + */ +public final class CppNames { + + private CppNames() {} + + /** First character upper-cased (e.g. {@code audioStream} -> {@code AudioStream}). */ + public static String capitalize(String s) { + return s.isEmpty() ? s : Character.toUpperCase(s.charAt(0)) + s.substring(1); + } + + /** First character lower-cased (e.g. {@code AudioStream} -> {@code audioStream}). */ + public static String decapitalize(String s) { + return s.isEmpty() ? s : Character.toLowerCase(s.charAt(0)) + s.substring(1); + } + + /** The private field name for a member: {@code m_} + decapitalized name. */ + public static String fieldName(String memberName) { + return "m_" + decapitalize(memberName); + } +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberOptions.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberOptions.java new file mode 100644 index 000000000000..25f73019a7a6 --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberOptions.java @@ -0,0 +1,29 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model; + +/** + * Options for {@link MemberRenderer#render}. Replaces the family of positional-boolean + * overloads so new rendering axes are added as a field here rather than as another overload. + */ +public final class MemberOptions { + private String exportMacro; + private String className; + private boolean emitHasBeenSet = true; + private String exclude = null; + private boolean wideIntegers = false; + + public MemberOptions exportMacro(String v) { this.exportMacro = v; return this; } + public MemberOptions className(String v) { this.className = v; return this; } + public MemberOptions emitHasBeenSet(boolean v) { this.emitHasBeenSet = v; return this; } + public MemberOptions exclude(String v) { this.exclude = v; return this; } + public MemberOptions wideIntegers(boolean v) { this.wideIntegers = v; return this; } + + public String exportMacro() { return exportMacro; } + public String className() { return className; } + public boolean emitHasBeenSet() { return emitHasBeenSet; } + public String exclude() { return exclude; } + public boolean wideIntegers() { return wideIntegers; } +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java index d08fd344f191..092a608bba88 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java @@ -29,6 +29,30 @@ public final class MemberRenderer { private MemberRenderer() { } + /** + * Renders the top-level {@code RequestId} accessor group emitted by result headers: + * {@code GetRequestId} / templated {@code SetRequestId} / templated {@code WithRequestId}. + * Callers decide whether to emit it (Query/EC2 do not) and separately emit the + * {@code m_requestId} field and its {@code HasBeenSet} flag in the private section. + */ + public static void renderRequestIdAccessors(CppWriter writer, String className) { + writer.write(""); + writer.write("///@{"); + writer.write(""); + writer.write("inline const Aws::String& GetRequestId() const { return m_requestId; }"); + writer.write("template "); + writer.openBlock("void SetRequestId(RequestIdT&& value) {", "}", () -> { + writer.write("m_requestIdHasBeenSet = true;"); + writer.write("m_requestId = std::forward(value);"); + }); + writer.write("template "); + writer.openBlock("$L& WithRequestId(RequestIdT&& value) {", "}", className, () -> { + writer.write("SetRequestId(std::forward(value));"); + writer.write("return *this;"); + }); + writer.write("///@}"); + } + /** * Writes the public accessor methods for all members of a structure shape. * @@ -51,7 +75,8 @@ private MemberRenderer() { */ public static void renderPublicSection(CppWriter writer, Shape shape, Model model, String exportMacro, String className) { - renderMembers(writer, shape, model, exportMacro, className, true, null, false); + render(writer, shape, model, + new MemberOptions().exportMacro(exportMacro).className(className).emitHasBeenSet(true)); } /** @@ -61,7 +86,8 @@ public static void renderPublicSection(CppWriter writer, Shape shape, public static void renderPublicSection(CppWriter writer, Shape shape, Model model, String exportMacro, String className, boolean wideIntegers) { - renderMembers(writer, shape, model, exportMacro, className, true, null, wideIntegers); + render(writer, shape, model, new MemberOptions() + .exportMacro(exportMacro).className(className).emitHasBeenSet(true).wideIntegers(wideIntegers)); } /** @@ -78,7 +104,8 @@ public static void renderPublicSection(CppWriter writer, Shape shape, public static void renderPublicSectionForResult(CppWriter writer, StructureShape shape, Model model, String exportMacro, String className, boolean wideIntegers) { - renderMembers(writer, shape, model, exportMacro, className, false, null, wideIntegers); + render(writer, shape, model, new MemberOptions() + .exportMacro(exportMacro).className(className).emitHasBeenSet(false).wideIntegers(wideIntegers)); } /** @@ -90,7 +117,18 @@ public static void renderPublicSectionForResult(CppWriter writer, StructureShape public static void renderPublicSectionForResultExcluding(CppWriter writer, StructureShape shape, Model model, String exportMacro, String className, String excludeMemberName, boolean wideIntegers) { - renderMembers(writer, shape, model, exportMacro, className, false, excludeMemberName, wideIntegers); + render(writer, shape, model, new MemberOptions() + .exportMacro(exportMacro).className(className).emitHasBeenSet(false) + .exclude(excludeMemberName).wideIntegers(wideIntegers)); + } + + /** + * Single entry point for rendering a structure's public accessor methods. + * See {@link MemberOptions} for the rendering axes. + */ + public static void render(CppWriter writer, Shape shape, Model model, MemberOptions opts) { + renderMembers(writer, shape, model, opts.exportMacro(), opts.className(), + opts.emitHasBeenSet(), opts.exclude(), opts.wideIntegers()); } /** Writes data member declarations, skipping {@code excludeMemberName}. */ @@ -126,22 +164,6 @@ public static void renderPrivateHasBeenSetFlagsExcluding(CppWriter writer, Struc } } - /** - * Shared implementation for rendering public accessor methods. - * - * @param writer the CppWriter to write to - * @param shape the structure shape whose members to render - * @param model the model (for resolving member targets) - * @param exportMacro the export macro (e.g., "AWS_KINESIS_API") - * @param className the C++ class name (e.g., "ChildShard") - * @param emitHasBeenSet whether to emit HasBeenSet() accessor methods - */ - private static void renderMembers(CppWriter writer, Shape shape, - Model model, String exportMacro, String className, - boolean emitHasBeenSet) { - renderMembers(writer, shape, model, exportMacro, className, emitHasBeenSet, null, false); - } - /** * Shared member-rendering implementation with an optional excluded member. Streaming * results emit their {@code @httpPayload} member via a dedicated {@code GetBody()} / @@ -161,7 +183,7 @@ private static void renderMembers(CppWriter writer, Shape shape, MemberShape member = entry.getValue(); Shape targetShape = model.expectShape(member.getTarget()); String cppType = CppTypeMapper.getCppType(targetShape, model, wideIntegers); - String fieldName = "m_" + decapitalize(memberName); + String fieldName = CppNames.fieldName(memberName); // Method names and template params use the capitalized member name to match the // legacy C2J convention (e.g. member "extendedKeyUsage" -> GetExtendedKeyUsage, // ExtendedKeyUsageHasBeenSet, template param ExtendedKeyUsageT). Field names keep @@ -335,7 +357,7 @@ private static void writeDataMember(CppWriter writer, MemberShape member, String boolean wideIntegers) { Shape targetShape = model.expectShape(member.getTarget()); String cppType = CppTypeMapper.getCppType(targetShape, model, wideIntegers); - String fieldName = "m_" + decapitalize(memberName); + String fieldName = CppNames.fieldName(memberName); if (member.hasTrait(IdempotencyTokenTrait.class)) { writer.write("$L $L{Aws::Utils::UUID::PseudoRandomUUID()};", cppType, fieldName); return; @@ -352,16 +374,11 @@ private static void writeDataMember(CppWriter writer, MemberShape member, String * Matches C2J's ModelClassMembersAndInlines.vm. */ private static void writeHasBeenSetFlag(CppWriter writer, MemberShape member, String memberName) { - String fieldName = "m_" + decapitalize(memberName); + String fieldName = CppNames.fieldName(memberName); boolean initialValue = member.hasTrait(IdempotencyTokenTrait.class); writer.write("bool $LHasBeenSet = $L;", fieldName, initialValue); } - private static String decapitalize(String name) { - if (name.isEmpty()) return name; - return Character.toLowerCase(name.charAt(0)) + name.substring(1); - } - /** * True if a container element / map key or value is passed to {@code Add*} by value rather * than by perfect-forwarding reference. Matches C2J: primitive and enum types are by-value @@ -372,8 +389,7 @@ private static boolean isByValueType(Shape shape) { } private static String capitalize(String name) { - if (name.isEmpty()) return name; - return Character.toUpperCase(name.charAt(0)) + name.substring(1); + return CppNames.capitalize(name); } private static final String[] UNSUPPORTED_HTML_TAGS = { diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ModelCodegenPlugin.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ModelCodegenPlugin.java index 797e20b09756..d3eeee702761 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ModelCodegenPlugin.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ModelCodegenPlugin.java @@ -64,7 +64,7 @@ public void execute(PluginContext context) { ModelGenerator generator = new ModelGenerator( transformedModel, processedService, writerDelegator, - serviceName, smithyServiceName, exportMacro, namespace); + smithyServiceName, exportMacro, namespace); generator.generateAll(); } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ModelGenerator.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ModelGenerator.java index 7b935207c72b..f8e4eb7f84f2 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ModelGenerator.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ModelGenerator.java @@ -31,7 +31,6 @@ public class ModelGenerator { private final Model model; private final ServiceShape service; private final CppWriterDelegator writerDelegator; - private final String serviceName; private final String smithyServiceName; private final String exportMacro; private final String namespace; @@ -39,12 +38,11 @@ public class ModelGenerator { private final ProtocolTraits protocolTraits; public ModelGenerator(Model model, ServiceShape service, CppWriterDelegator writerDelegator, - String serviceName, String smithyServiceName, + String smithyServiceName, String exportMacro, String namespace) { this.model = model; this.service = service; this.writerDelegator = writerDelegator; - this.serviceName = serviceName; this.smithyServiceName = smithyServiceName; this.exportMacro = exportMacro; this.namespace = namespace; @@ -54,39 +52,23 @@ public ModelGenerator(Model model, ServiceShape service, CppWriterDelegator writ public void generateAll() { ClassifiedShapes classified = ShapeClassifier.classify(model, service, protocol); - List renderers = buildRenderers(classified); + RenderContext ctx = new RenderContext(model, service, protocolTraits, + namespace, exportMacro, smithyServiceName); + List renderers = buildRenderers(classified, ctx); for (ShapeRenderer renderer : renderers) { renderer.render(writerDelegator); } } - private List buildRenderers(ClassifiedShapes classified) { + private List buildRenderers(ClassifiedShapes classified, RenderContext ctx) { List renderers = new ArrayList<>(); - - renderers.add(new EnumShapeRenderer( - classified.enums(), namespace, exportMacro, smithyServiceName)); - - renderers.add(new SubObjectRenderer( - classified.subObjects(), model, service, protocolTraits, - namespace, exportMacro, serviceName, smithyServiceName)); - - renderers.add(new RequestRenderer( - classified.requests(), model, service, protocolTraits, - namespace, exportMacro, smithyServiceName)); - - renderers.add(new ResultRenderer( - classified.results(), model, service, protocolTraits, - namespace, exportMacro, smithyServiceName)); - - renderers.add(new EventStreamRenderer( - classified.eventStreamHandlers(), model, service, protocolTraits, - namespace, exportMacro, smithyServiceName)); - - renderers.add(new OutgoingEventStreamRenderer( - classified.outgoingEventStreams(), model, service, protocolTraits, - namespace, exportMacro, smithyServiceName)); - + renderers.add(new EnumShapeRenderer(classified.enums(), ctx)); + renderers.add(new SubObjectRenderer(classified.subObjects(), ctx)); + renderers.add(new RequestRenderer(classified.requests(), ctx)); + renderers.add(new ResultRenderer(classified.results(), ctx)); + renderers.add(new EventStreamRenderer(classified.eventStreamHandlers(), ctx)); + renderers.add(new OutgoingEventStreamRenderer(classified.outgoingEventStreams(), ctx)); return renderers; } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RenderContext.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RenderContext.java new file mode 100644 index 000000000000..0486fdfd94a8 --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RenderContext.java @@ -0,0 +1,29 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model; + +import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.ProtocolTraits; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.ServiceShape; + +/** + * Immutable bundle of the per-service inputs every {@link ShapeRenderer} needs. + * Replaces the repeated 6-7 positional constructor arguments so adding a shared + * input is a single-field change rather than an edit to every renderer. + * + * @param model the transformed Smithy model + * @param service the service shape being generated + * @param protocolTraits the resolved protocol rendering strategy + * @param namespace the C++ model namespace (e.g. "IAM") + * @param exportMacro the export macro (e.g. "AWS_IAM_API") + * @param smithyServiceName the on-disk service directory name (e.g. "iam") + */ +public record RenderContext( + Model model, + ServiceShape service, + ProtocolTraits protocolTraits, + String namespace, + String exportMacro, + String smithyServiceName) {} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ShapeClassifier.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ShapeClassifier.java index 4b68d03553af..5d57f27da337 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ShapeClassifier.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ShapeClassifier.java @@ -37,14 +37,6 @@ */ public final class ShapeClassifier { - /** - * Classification bucket for a shape. - */ - public enum Classification { - REQUEST, RESULT, SUB_OBJECT, ENUM, - EVENT_STREAM_HANDLER, BLOB_PAYLOAD_EVENT, OUTGOING_EVENT_STREAM, SKIP - } - /** * Associates an operation input shape with its parent operation. * @@ -79,7 +71,6 @@ public record EventStreamInfo(String operationName, StructureShape requestShape, * @param subObjects remaining StructureShape/UnionShape reachable from operations * @param enums EnumShape or StringShape with @enum trait * @param eventStreamHandlers operation + request/result shape tuples for event stream handlers - * @param blobPayloadEvents event shapes with blob payloads (header only) * @param outgoingEventStreams outgoing event stream shapes (header only) */ public record ClassifiedShapes( @@ -88,7 +79,6 @@ public record ClassifiedShapes( List subObjects, List enums, List eventStreamHandlers, - List blobPayloadEvents, List outgoingEventStreams ) {} @@ -118,7 +108,6 @@ public static ClassifiedShapes classify(Model model, ServiceShape service, Proto List subObjects = new ArrayList<>(); List enums = new ArrayList<>(); List eventStreamHandlers = new ArrayList<>(); - List blobPayloadEvents = new ArrayList<>(); List outgoingEventStreams = new ArrayList<>(); // Collect operation inputs/outputs and identify event stream handlers @@ -181,7 +170,7 @@ public static ClassifiedShapes classify(Model model, ServiceShape service, Proto } return new ClassifiedShapes(requests, results, subObjects, enums, - eventStreamHandlers, blobPayloadEvents, outgoingEventStreams); + eventStreamHandlers, outgoingEventStreams); } /** diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraits.java index 585d3e399577..e498c03bfc2f 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraits.java @@ -165,14 +165,14 @@ public void writeResultSerdeImpls(CppWriter writer, String className, StructureS @Override public void writeRequestMethodDecls(CppWriter writer, String exportMacro, StructureShape shape, OperationShape operation, Model model) { - if (emitsSerializePayload(operation, model)) { + if (RequestBindings.emitsSerializePayload(operation, model)) { writer.write("$L Aws::String SerializePayload() const override;", exportMacro); } // CBOR always emits GetRequestSpecificHeaders: it attaches protocol headers // (content-type / smithy-protocol / accept) regardless of member bindings. writer.write(""); writeGetRequestSpecificHeadersDecl(writer, exportMacro); - if (requestHasQueryStringMembers(shape, model)) { + if (RequestBindings.hasQueryStringMembers(shape, model)) { writer.write(""); writeAddQueryStringParametersDecl(writer, exportMacro); } @@ -183,7 +183,7 @@ public void writeRequestMethodImpls(CppWriter writer, String className, StructureShape shape, OperationShape operation, ServiceShape service, Model model) { boolean hasRequest = !operation.getInputShape().equals(UnitTypeTrait.UNIT); - if (emitsSerializePayload(operation, model)) { + if (RequestBindings.emitsSerializePayload(operation, model)) { if (hasRequest) { writer.openBlock("Aws::String $L::SerializePayload() const {", "}", className, () -> { writer.write("Aws::Crt::Cbor::CborEncoder encoder;"); @@ -212,7 +212,7 @@ public void writeRequestMethodImpls(CppWriter writer, String className, writer.write("headers.emplace(Aws::Http::ACCEPT_HEADER, Aws::CBOR_CONTENT_TYPE);"); writer.write("return headers;"); }); - if (requestHasQueryStringMembers(shape, model)) { + if (RequestBindings.hasQueryStringMembers(shape, model)) { writer.write(""); writeAddQueryStringParametersImpl(writer, className); } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraits.java index d5d7ae537fd0..a40cc03c290d 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraits.java @@ -162,14 +162,14 @@ public void writeRequestMethodDecls(CppWriter writer, String exportMacro, StructureShape shape, OperationShape operation, Model model) { // A raw-streaming-payload request sends its body via the streaming base class, so no // SerializePayload is emitted (matches C2J). - if (emitsSerializePayload(operation, model)) { + if (RequestBindings.emitsSerializePayload(operation, model)) { writer.write("$L Aws::String SerializePayload() const override;", exportMacro); } - if (hasTargetHeader() || requestHasHeaderMembers(shape, model)) { + if (hasTargetHeader() || RequestBindings.hasHeaderMembers(shape, model)) { writer.write(""); writeGetRequestSpecificHeadersDecl(writer, exportMacro); } - if (requestHasQueryStringMembers(shape, model)) { + if (RequestBindings.hasQueryStringMembers(shape, model)) { writer.write(""); writeAddQueryStringParametersDecl(writer, exportMacro); } @@ -179,15 +179,15 @@ public void writeRequestMethodDecls(CppWriter writer, String exportMacro, public void writeRequestMethodImpls(CppWriter writer, String className, StructureShape shape, OperationShape operation, ServiceShape service, Model model) { - if (emitsSerializePayload(operation, model)) { + if (RequestBindings.emitsSerializePayload(operation, model)) { String payloadBody = protocol == Protocol.JSON ? "\"{}\"" : "{}"; writer.write("Aws::String $L::SerializePayload() const { return $L; }", className, payloadBody); } - if (hasTargetHeader() || requestHasHeaderMembers(shape, model)) { + if (hasTargetHeader() || RequestBindings.hasHeaderMembers(shape, model)) { writer.write(""); writeGetRequestSpecificHeadersImpl(writer, className, shape, operation, service, model); } - if (requestHasQueryStringMembers(shape, model)) { + if (RequestBindings.hasQueryStringMembers(shape, model)) { writer.write(""); writeAddQueryStringParametersImpl(writer, className); } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraits.java index 5384d25bb484..761648644314 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraits.java @@ -5,17 +5,13 @@ package com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol; import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.CppNames; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; -import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeClassifier; import software.amazon.smithy.model.Model; 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.StructureShape; -import software.amazon.smithy.model.traits.HttpHeaderTrait; -import software.amazon.smithy.model.traits.HttpPrefixHeadersTrait; -import software.amazon.smithy.model.traits.HttpQueryTrait; -import software.amazon.smithy.model.traits.HttpQueryParamsTrait; /** * Owns every protocol-specific rendering decision for generated model code. @@ -109,7 +105,7 @@ default void writeResultStatusCodeMembers(CppWriter writer, StructureShape shape for (java.util.Map.Entry entry : shape.getAllMembers().entrySet()) { if (entry.getValue().hasTrait(software.amazon.smithy.model.traits.HttpResponseCodeTrait.class)) { String name = entry.getKey(); - String field = "m_" + Character.toLowerCase(name.charAt(0)) + name.substring(1); + String field = CppNames.fieldName(name); writer.write("$L = static_cast(result.GetResponseCode());", field); writer.write("$LHasBeenSet = true;", field); } @@ -170,39 +166,6 @@ default boolean resultHasTopLevelRequestId() { return true; } - /** True when any request member binds to an HTTP header (httpHeader / httpPrefixHeaders). */ - default boolean requestHasHeaderMembers(StructureShape shape, Model model) { - for (MemberShape m : shape.getAllMembers().values()) { - if (m.hasTrait(HttpHeaderTrait.class) || m.hasTrait(HttpPrefixHeadersTrait.class)) { - return true; - } - } - return false; - } - - /** True when any request member binds to the query string (httpQuery / httpQueryParams). */ - default boolean requestHasQueryStringMembers(StructureShape shape, Model model) { - for (MemberShape m : shape.getAllMembers().values()) { - if (m.hasTrait(HttpQueryTrait.class) || m.hasTrait(HttpQueryParamsTrait.class)) { - return true; - } - } - return false; - } - - /** - * True when the request should emit a declared {@code SerializePayload()} method through the - * normal path. C2J omits it (RequestHeader.vm keys only on {@code hasStreamMembers()} / - * {@code hasEventStreamMembers()}) for both a raw streaming {@code @httpPayload} member (the - * streaming base class sends the body via {@code GetBody}) and an event-stream input member - * (which gets an inline empty SerializePayload + {@code GetBody()} override rendered by the - * request renderer). The gate is protocol-agnostic, so every protocol shares it. - */ - default boolean emitsSerializePayload(OperationShape operation, Model model) { - return !ShapeClassifier.isRawStreamingPayloadRequest(operation, model) - && !ShapeClassifier.isEventStreamRequestOperation(operation, model); - } - default void writeGetRequestSpecificHeadersDecl(CppWriter writer, String exportMacro) { writer.write("$L Aws::Http::HeaderValueCollection GetRequestSpecificHeaders() const override;", exportMacro); } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/QueryXmlProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/QueryXmlProtocolTraits.java index 6554108ef069..ee13e9156e9d 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/QueryXmlProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/QueryXmlProtocolTraits.java @@ -192,14 +192,14 @@ public void writeResultSerdeImpls(CppWriter writer, String className, StructureS @Override public void writeRequestMethodDecls(CppWriter writer, String exportMacro, StructureShape shape, OperationShape operation, Model model) { - if (emitsSerializePayload(operation, model)) { + if (RequestBindings.emitsSerializePayload(operation, model)) { writer.write("$L Aws::String SerializePayload() const override;", exportMacro); } - if (requestHasHeaderMembers(shape, model)) { + if (RequestBindings.hasHeaderMembers(shape, model)) { writer.write(""); writeGetRequestSpecificHeadersDecl(writer, exportMacro); } - if (requestHasQueryStringMembers(shape, model)) { + if (RequestBindings.hasQueryStringMembers(shape, model)) { writer.write(""); writeAddQueryStringParametersDecl(writer, exportMacro); } @@ -221,14 +221,14 @@ public void writeRequestMethodDecls(CppWriter writer, String exportMacro, public void writeRequestMethodImpls(CppWriter writer, String className, StructureShape shape, OperationShape operation, ServiceShape service, Model model) { - if (emitsSerializePayload(operation, model)) { + if (RequestBindings.emitsSerializePayload(operation, model)) { writer.write("Aws::String $L::SerializePayload() const { return {}; }", className); } - if (requestHasHeaderMembers(shape, model)) { + if (RequestBindings.hasHeaderMembers(shape, model)) { writer.write(""); writeGetRequestSpecificHeadersImpl(writer, className, shape, operation, service, model); } - if (requestHasQueryStringMembers(shape, model)) { + if (RequestBindings.hasQueryStringMembers(shape, model)) { writer.write(""); writeAddQueryStringParametersImpl(writer, className); } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RequestBindings.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RequestBindings.java new file mode 100644 index 000000000000..fec62335a279 --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RequestBindings.java @@ -0,0 +1,54 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol; + +import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeClassifier; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.MemberShape; +import software.amazon.smithy.model.shapes.OperationShape; +import software.amazon.smithy.model.shapes.StructureShape; +import software.amazon.smithy.model.traits.HttpHeaderTrait; +import software.amazon.smithy.model.traits.HttpPrefixHeadersTrait; +import software.amazon.smithy.model.traits.HttpQueryParamsTrait; +import software.amazon.smithy.model.traits.HttpQueryTrait; + +/** + * Protocol-agnostic queries over a request (operation input) structure's HTTP bindings. + * These do not vary by wire protocol, so they live here rather than on {@link ProtocolTraits}. + */ +final class RequestBindings { + + private RequestBindings() {} + + /** True when any request member binds to an HTTP header (httpHeader / httpPrefixHeaders). */ + static boolean hasHeaderMembers(StructureShape shape, Model model) { + for (MemberShape m : shape.getAllMembers().values()) { + if (m.hasTrait(HttpHeaderTrait.class) || m.hasTrait(HttpPrefixHeadersTrait.class)) { + return true; + } + } + return false; + } + + /** True when any request member binds to the query string (httpQuery / httpQueryParams). */ + static boolean hasQueryStringMembers(StructureShape shape, Model model) { + for (MemberShape m : shape.getAllMembers().values()) { + if (m.hasTrait(HttpQueryTrait.class) || m.hasTrait(HttpQueryParamsTrait.class)) { + return true; + } + } + return false; + } + + /** + * True when the request emits a declared {@code SerializePayload()} through the normal path. + * C2J omits it for a raw streaming {@code @httpPayload} member and for an event-stream input + * member. The gate is protocol-agnostic. + */ + static boolean emitsSerializePayload(OperationShape operation, Model model) { + return !ShapeClassifier.isRawStreamingPayloadRequest(operation, model) + && !ShapeClassifier.isEventStreamRequestOperation(operation, model); + } +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RestXmlProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RestXmlProtocolTraits.java index ea657c02a2ef..d59d4eff0bd6 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RestXmlProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RestXmlProtocolTraits.java @@ -137,14 +137,14 @@ public void writeResultSerdeImpls(CppWriter writer, String className, StructureS @Override public void writeRequestMethodDecls(CppWriter writer, String exportMacro, StructureShape shape, OperationShape operation, Model model) { - if (emitsSerializePayload(operation, model)) { + if (RequestBindings.emitsSerializePayload(operation, model)) { writer.write("$L Aws::String SerializePayload() const override;", exportMacro); } - if (requestHasHeaderMembers(shape, model)) { + if (RequestBindings.hasHeaderMembers(shape, model)) { writer.write(""); writeGetRequestSpecificHeadersDecl(writer, exportMacro); } - if (requestHasQueryStringMembers(shape, model)) { + if (RequestBindings.hasQueryStringMembers(shape, model)) { writer.write(""); writeAddQueryStringParametersDecl(writer, exportMacro); } @@ -154,14 +154,14 @@ public void writeRequestMethodDecls(CppWriter writer, String exportMacro, public void writeRequestMethodImpls(CppWriter writer, String className, StructureShape shape, OperationShape operation, ServiceShape service, Model model) { - if (emitsSerializePayload(operation, model)) { + if (RequestBindings.emitsSerializePayload(operation, model)) { writer.write("Aws::String $L::SerializePayload() const { return {}; }", className); } - if (requestHasHeaderMembers(shape, model)) { + if (RequestBindings.hasHeaderMembers(shape, model)) { writer.write(""); writeGetRequestSpecificHeadersImpl(writer, className, shape, operation, service, model); } - if (requestHasQueryStringMembers(shape, model)) { + if (RequestBindings.hasQueryStringMembers(shape, model)) { writer.write(""); writeAddQueryStringParametersImpl(writer, className); } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EnumShapeRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EnumShapeRenderer.java index 9b004db6dea9..830a33d5ae29 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EnumShapeRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EnumShapeRenderer.java @@ -7,6 +7,7 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; import com.amazonaws.util.awsclientsmithygenerator.generators.model.CppTypeMapper; import com.amazonaws.util.awsclientsmithygenerator.generators.model.EnumRenderer; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.RenderContext; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeRenderer; import software.amazon.smithy.model.shapes.Shape; @@ -18,29 +19,24 @@ public final class EnumShapeRenderer implements ShapeRenderer { private final List enumShapes; - private final String namespace; - private final String exportMacro; - private final String smithyServiceName; + private final RenderContext ctx; - public EnumShapeRenderer(List enumShapes, String namespace, - String exportMacro, String smithyServiceName) { + public EnumShapeRenderer(List enumShapes, RenderContext ctx) { this.enumShapes = enumShapes; - this.namespace = namespace; - this.exportMacro = exportMacro; - this.smithyServiceName = smithyServiceName; + this.ctx = ctx; } @Override public void render(CppWriterDelegator writerDelegator) { for (Shape enumShape : enumShapes) { String name = CppTypeMapper.cppShapeName(enumShape); - String headerFile = "include/aws/" + smithyServiceName + "/model/" + name + ".h"; + String headerFile = "include/aws/" + ctx.smithyServiceName() + "/model/" + name + ".h"; writerDelegator.useFileWriter(headerFile, writer -> - EnumRenderer.renderHeader(writer, enumShape, namespace, exportMacro, smithyServiceName)); + EnumRenderer.renderHeader(writer, enumShape, ctx.namespace(), ctx.exportMacro(), ctx.smithyServiceName())); String sourceFile = "source/model/" + name + ".cpp"; writerDelegator.useFileWriter(sourceFile, writer -> - EnumRenderer.renderSource(writer, enumShape, namespace, exportMacro, smithyServiceName)); + EnumRenderer.renderSource(writer, enumShape, ctx.namespace(), ctx.exportMacro(), ctx.smithyServiceName())); } } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EventStreamRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EventStreamRenderer.java index 9878e45e57b8..d20342148de8 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EventStreamRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EventStreamRenderer.java @@ -6,16 +6,16 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.CppNames; import com.amazonaws.util.awsclientsmithygenerator.generators.model.CppTypeMapper; import com.amazonaws.util.awsclientsmithygenerator.generators.model.MemberRenderer; import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.FileKind; import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.ProtocolTraits; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.RenderContext; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeClassifier; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeClassifier.EventStreamInfo; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeRenderer; -import software.amazon.smithy.model.Model; import software.amazon.smithy.model.shapes.MemberShape; -import software.amazon.smithy.model.shapes.ServiceShape; import software.amazon.smithy.model.shapes.Shape; import software.amazon.smithy.model.shapes.StructureShape; import software.amazon.smithy.model.shapes.UnionShape; @@ -39,23 +39,11 @@ public final class EventStreamRenderer implements ShapeRenderer { private final List eventStreams; - private final Model model; - private final ServiceShape service; - private final ProtocolTraits protocolTraits; - private final String namespace; - private final String exportMacro; - private final String smithyServiceName; - - public EventStreamRenderer(List eventStreams, Model model, ServiceShape service, - ProtocolTraits protocolTraits, String namespace, String exportMacro, - String smithyServiceName) { + private final RenderContext ctx; + + public EventStreamRenderer(List eventStreams, RenderContext ctx) { this.eventStreams = eventStreams; - this.model = model; - this.service = service; - this.protocolTraits = protocolTraits; - this.namespace = namespace; - this.exportMacro = exportMacro; - this.smithyServiceName = smithyServiceName; + this.ctx = ctx; } @Override @@ -80,7 +68,7 @@ public void render(CppWriterDelegator writerDelegator) { /** Finds the @streaming union targeted by a member of the result structure, if any. */ private Optional findStreamingUnion(StructureShape resultShape) { for (MemberShape member : resultShape.getAllMembers().values()) { - Shape target = model.expectShape(member.getTarget()); + Shape target = ctx.model().expectShape(member.getTarget()); if (target.isUnionShape() && target.hasTrait(StreamingTrait.class)) { return target.asUnionShape(); } @@ -91,7 +79,7 @@ private Optional findStreamingUnion(StructureShape resultShape) { /** Splits union members into events (non-exception) and exceptions, preserving order. */ private void partitionMembers(UnionShape union, List events, List exceptions) { for (MemberShape member : union.getAllMembers().values()) { - Shape target = model.expectShape(member.getTarget()); + Shape target = ctx.model().expectShape(member.getTarget()); if (target.hasTrait(ErrorTrait.class)) { exceptions.add(member); } else { @@ -111,8 +99,8 @@ private String eventShapeName(MemberShape member) { * and non-modeled ones as the generic {@code Error} wrapper. */ private boolean isModeledException(MemberShape exc) { - StructureShape target = model.expectShape(exc.getTarget(), StructureShape.class); - return ShapeClassifier.isModeledException(target, protocolTraits.protocol()); + StructureShape target = ctx.model().expectShape(exc.getTarget(), StructureShape.class); + return ShapeClassifier.isModeledException(target, ctx.protocolTraits().protocol()); } /** The C++ type for an exception member: concrete shape name if modeled, else {@code errorType}. */ @@ -135,22 +123,20 @@ private String enumConstant(MemberShape member) { private void renderHandlerHeader(CppWriterDelegator writerDelegator, String opName, List events) { String className = opName + "Handler"; - String fileName = "include/aws/" + smithyServiceName + "/model/" + className + ".h"; + String fileName = "include/aws/" + ctx.smithyServiceName() + "/model/" + className + ".h"; writerDelegator.useFileWriter(fileName, writer -> { writer.write("#pragma once"); writer.write("#include "); writer.write("#include "); writer.write("#include "); - writer.write("#include ", smithyServiceName, namespace); - writer.write("#include ", smithyServiceName, namespace); - writer.write("#include ", smithyServiceName, opName); + writer.write("#include ", ctx.smithyServiceName(), ctx.namespace()); + writer.write("#include ", ctx.smithyServiceName(), ctx.namespace()); + writer.write("#include ", ctx.smithyServiceName(), opName); for (MemberShape event : events) { - writer.write("#include ", smithyServiceName, eventShapeName(event)); + writer.write("#include ", ctx.smithyServiceName(), eventShapeName(event)); } writer.write(""); - writer.writeNamespaceOpen("Aws"); - writer.writeNamespaceOpen(namespace); - writer.writeNamespaceOpen("Model"); + ModelFile.modelNamespace(writer, ctx.namespace(), () -> { // EventType enum StringBuilder enumBody = new StringBuilder("enum class ") @@ -170,16 +156,16 @@ private void renderHandlerHeader(CppWriterDelegator writerDelegator, String opNa String ev = eventShapeName(event); writer.write("typedef std::function $1LCallback;", ev); } - writer.write("typedef std::function& error)> ErrorCallback;", namespace); + writer.write("typedef std::function& error)> ErrorCallback;", ctx.namespace()); writer.write(""); writer.dedent(); writer.write("public:"); writer.indent(); - writer.write("$1L $2L();", exportMacro, className); - writer.write("$1L $2L& operator=(const $2L&) = default;", exportMacro, className); - writer.write("$1L $2L(const $2L&) = default;", exportMacro, className); + writer.write("$1L $2L();", ctx.exportMacro(), className); + writer.write("$1L $2L& operator=(const $2L&) = default;", ctx.exportMacro(), className); + writer.write("$1L $2L(const $2L&) = default;", ctx.exportMacro(), className); writer.write(""); - writer.write("$1L virtual void OnEvent() override;", exportMacro); + writer.write("$1L virtual void OnEvent() override;", ctx.exportMacro()); writer.write(""); writer.write("///@{"); writer.write("/**"); @@ -209,9 +195,9 @@ private void renderHandlerHeader(CppWriterDelegator writerDelegator, String opNa writer.dedent(); writer.write("private:"); writer.indent(); - writer.write("$1L void HandleEventInMessage();", exportMacro); - writer.write("$1L void HandleErrorInMessage();", exportMacro); - writer.write("$1L void MarshallError(const Aws::String& errorCode, const Aws::String& errorMessage);", exportMacro); + writer.write("$1L void HandleEventInMessage();", ctx.exportMacro()); + writer.write("$1L void HandleErrorInMessage();", ctx.exportMacro()); + writer.write("$1L void MarshallError(const Aws::String& errorCode, const Aws::String& errorMessage);", ctx.exportMacro()); writer.write(""); writer.write("$1LInitialResponseCallbackEx m_onInitialResponse;", opName); for (MemberShape event : events) { @@ -223,14 +209,11 @@ private void renderHandlerHeader(CppWriterDelegator writerDelegator, String opNa writer.write(""); writer.writeNamespaceOpen(opName + "EventMapper"); - writer.write("$1L $2LEventType Get$2LEventTypeForName(const Aws::String& name);", exportMacro, opName); + writer.write("$1L $2LEventType Get$2LEventTypeForName(const Aws::String& name);", ctx.exportMacro(), opName); writer.write(""); - writer.write("$1L Aws::String GetNameFor$2LEventType($2LEventType value);", exportMacro, opName); + writer.write("$1L Aws::String GetNameFor$2LEventType($2LEventType value);", ctx.exportMacro(), opName); writer.writeNamespaceClose(opName + "EventMapper"); - - writer.writeNamespaceClose("Model"); - writer.writeNamespaceClose(namespace); - writer.writeNamespaceClose("Aws"); + }); }); } @@ -245,21 +228,19 @@ private void renderHandlerSource(CppWriterDelegator writerDelegator, String opNa includes.add("aws/core/client/CoreErrors.h"); includes.add("aws/core/utils/event/EventStreamErrors.h"); includes.add("aws/core/utils/logging/LogMacros.h"); - includes.add("aws/" + smithyServiceName + "/" + namespace + "ErrorMarshaller.h"); - includes.add("aws/" + smithyServiceName + "/model/" + opName + "Handler.h"); - includes.addAll(protocolTraits.serdeIncludes(FileKind.EVENT_HANDLER_SOURCE)); + includes.add("aws/" + ctx.smithyServiceName() + "/" + ctx.namespace() + "ErrorMarshaller.h"); + includes.add("aws/" + ctx.smithyServiceName() + "/model/" + opName + "Handler.h"); + includes.addAll(ctx.protocolTraits().serdeIncludes(FileKind.EVENT_HANDLER_SOURCE)); IncludeSets.emit(writer, includes); writer.write(""); - writer.write("using namespace Aws::$1L::Model;", namespace); + writer.write("using namespace Aws::$1L::Model;", ctx.namespace()); writer.write("using namespace Aws::Utils::Event;"); - IncludeSets.emitUsings(writer, protocolTraits.serdeUsings(FileKind.EVENT_HANDLER_SOURCE)); + IncludeSets.emitUsings(writer, ctx.protocolTraits().serdeUsings(FileKind.EVENT_HANDLER_SOURCE)); writer.write(""); writer.write("AWS_CORE_API extern const char MESSAGE_LOWER_CASE[];"); writer.write("AWS_CORE_API extern const char MESSAGE_CAMEL_CASE[];"); writer.write(""); - writer.writeNamespaceOpen("Aws"); - writer.writeNamespaceOpen(namespace); - writer.writeNamespaceOpen("Model"); + ModelFile.modelNamespace(writer, ctx.namespace(), () -> { writer.write("using namespace Aws::Client;"); writer.write(""); writer.write("static const char $1L[] = \"$2LHandler\";", tag, opName); @@ -276,8 +257,8 @@ private void renderHandlerSource(CppWriterDelegator writerDelegator, String opNa writer.write("AWS_LOGSTREAM_TRACE($1L, \"$2L received.\");", tag, ev); }); } - writer.openBlock("m_onError = [&](const AWSError<$1LErrors>& error) {", "};", namespace, () -> { - writer.write("AWS_LOGSTREAM_TRACE($1L, \"$2L Errors received, \" << error);", tag, namespace); + writer.openBlock("m_onError = [&](const AWSError<$1LErrors>& error) {", "};", ctx.namespace(), () -> { + writer.write("AWS_LOGSTREAM_TRACE($1L, \"$2L Errors received, \" << error);", tag, ctx.namespace()); }); }); writer.write(""); @@ -287,7 +268,7 @@ private void renderHandlerSource(CppWriterDelegator writerDelegator, String opNa writer.openBlock("if (!*this) {", "}", () -> { writer.write("AWSError error = EventStreamErrorsMapper::GetAwsErrorForEventStreamError(GetInternalError());"); writer.write("error.SetMessage(GetEventPayloadAsString());"); - writer.write("m_onError(AWSError<$1LErrors>(error));", namespace); + writer.write("m_onError(AWSError<$1LErrors>(error));", ctx.namespace()); writer.write("return;"); }); writer.write("const auto& headers = GetEventHeaders();"); @@ -328,7 +309,7 @@ private void renderHandlerSource(CppWriterDelegator writerDelegator, String opNa }); for (MemberShape event : events) { writer.openBlock("case $1LEventType::$2L: {", "}", opName, enumConstant(event), () -> { - protocolTraits.writeEventPayloadDecode(writer, eventShapeName(event), + ctx.protocolTraits().writeEventPayloadDecode(writer, eventShapeName(event), "m_on" + eventShapeName(event)); writer.write("break;"); }); @@ -357,7 +338,7 @@ private void renderHandlerSource(CppWriterDelegator writerDelegator, String opNa writer.write("errorHeaderIter = headers.find(ERROR_MESSAGE_HEADER);"); writer.openBlock("if (errorHeaderIter == headers.end()) {", "}", () -> { writer.write("// TODO: read error message from payload once protocol-specific serde lands"); - protocolTraits.writeErrorPayloadParse(writer); + ctx.protocolTraits().writeErrorPayloadParse(writer); }); writer.openBlock("else {", "}", () -> { writer.write("errorMessage = errorHeaderIter->second.GetEventHeaderValueAsString();"); @@ -368,7 +349,7 @@ private void renderHandlerSource(CppWriterDelegator writerDelegator, String opNa // MarshallError (verbatim from C2J) writer.openBlock("void $1L::MarshallError(const Aws::String& errorCode, const Aws::String& errorMessage) {", "}", className, () -> { - writer.write("$1LErrorMarshaller errorMarshaller;", namespace); + writer.write("$1LErrorMarshaller errorMarshaller;", ctx.namespace()); writer.write("AWSError error;"); writer.openBlock("if (errorCode.empty()) {", "}", () -> { writer.write("error = AWSError(CoreErrors::UNKNOWN, \"\", errorMessage, false);"); @@ -385,7 +366,7 @@ private void renderHandlerSource(CppWriterDelegator writerDelegator, String opNa writer.write("error = AWSError(CoreErrors::UNKNOWN, errorCode, \"Unable to parse ExceptionName: \" + errorCode + \" Message: \" + errorMessage, false);"); }); }); - writer.write("m_onError(AWSError<$1LErrors>(error));", namespace); + writer.write("m_onError(AWSError<$1LErrors>(error));", ctx.namespace()); }); writer.write(""); @@ -423,10 +404,7 @@ private void renderHandlerSource(CppWriterDelegator writerDelegator, String opNa }); }); writer.writeNamespaceClose(opName + "EventMapper"); - - writer.writeNamespaceClose("Model"); - writer.writeNamespaceClose(namespace); - writer.writeNamespaceClose("Aws"); + }); }); } @@ -441,7 +419,7 @@ private StructureShape initialResponseShape(String opName, StructureShape result StructureShape.Builder builder = StructureShape.builder() .id("com.amazonaws.smithy.synthetic#" + opName + "InitialResponse"); for (MemberShape member : resultShape.getAllMembers().values()) { - Shape target = model.expectShape(member.getTarget()); + Shape target = ctx.model().expectShape(member.getTarget()); if (target.isUnionShape() && target.hasTrait(StreamingTrait.class)) { continue; } @@ -457,79 +435,72 @@ private void renderInitialResponse(CppWriterDelegator writerDelegator, String op StructureShape shape = initialResponseShape(opName, resultShape); boolean hasMembers = !shape.getAllMembers().isEmpty(); - String headerFile = "include/aws/" + smithyServiceName + "/model/" + className + ".h"; + String headerFile = "include/aws/" + ctx.smithyServiceName() + "/model/" + className + ".h"; writerDelegator.useFileWriter(headerFile, writer -> { writer.write("#pragma once"); List includes = new java.util.ArrayList<>(); includes.add(""); - includes.add(""); - includes.addAll(CppTypeMapper.getIncludesForShape(shape, model, smithyServiceName)); - for (String include : new java.util.TreeSet<>(includes)) { - writer.write("#include $L", include); - } + includes.add(""); + includes.addAll(CppTypeMapper.getIncludesForShape(shape, ctx.model(), ctx.smithyServiceName())); + IncludeSets.emitAngleIncludes(writer, includes); if (hasMembers) { writer.write(""); writer.write("#include "); } writer.write(""); - writer.writeNamespaceOpen("Aws"); - protocolTraits.writeShapeForwardDeclarations(writer); - writer.writeNamespaceOpen(namespace); - writer.writeNamespaceOpen("Model"); + writer.withNamespace("Aws", () -> { + ctx.protocolTraits().writeShapeForwardDeclarations(writer); + writer.withNamespace(ctx.namespace(), () -> + writer.withNamespace("Model", () -> { writer.write(""); writer.openBlock("class $L {", "};", className, () -> { writer.write("public:"); // The header-collection ctor sits before the serialize method (mainline ordering). - protocolTraits.writeSerdeMethodDecls(writer, exportMacro, className, - () -> writer.write("$1L $2L(const Http::HeaderValueCollection& responseHeaders);", exportMacro, className)); + ctx.protocolTraits().writeSerdeMethodDecls(writer, ctx.exportMacro(), className, + () -> writer.write("$1L $2L(const Http::HeaderValueCollection& responseHeaders);", ctx.exportMacro(), className)); // Accessors + private section for the result's non-streaming members. A memberless // InitialResponse ends right after its serde decls (no private:), matching C2J. if (hasMembers) { - boolean wideIntegers = protocolTraits.widensIntegers(); + boolean wideIntegers = ctx.protocolTraits().widensIntegers(); writer.write(""); - MemberRenderer.renderPublicSection(writer, shape, model, exportMacro, className, wideIntegers); + MemberRenderer.renderPublicSection(writer, shape, ctx.model(), ctx.exportMacro(), className, wideIntegers); writer.dedent(); writer.write("private:"); writer.indent(); - MemberRenderer.renderPrivateSection(writer, shape, model, wideIntegers); + MemberRenderer.renderPrivateSection(writer, shape, ctx.model(), wideIntegers); } }); writer.write(""); - writer.writeNamespaceClose("Model"); - writer.writeNamespaceClose(namespace); - writer.writeNamespaceClose("Aws"); + })); + }); }); String sourceFile = "source/model/" + className + ".cpp"; writerDelegator.useFileWriter(sourceFile, writer -> { List includes = new java.util.ArrayList<>(); includes.add("aws/core/utils/StringUtils.h"); - includes.add("aws/" + smithyServiceName + "/model/" + className + ".h"); + includes.add("aws/" + ctx.smithyServiceName() + "/model/" + className + ".h"); includes.add("utility"); - includes.addAll(protocolTraits.serdeIncludes(FileKind.INITIAL_RESPONSE_SOURCE)); + includes.addAll(ctx.protocolTraits().serdeIncludes(FileKind.INITIAL_RESPONSE_SOURCE)); // Serde-implementation includes derived from the initial-response members (e.g. // AWSStringStream.h for the header-bound members), matching C2J computeSourceIncludes. - includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, model, smithyServiceName)); + includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, ctx.model(), ctx.smithyServiceName())); IncludeSets.emit(writer, includes); writer.write(""); - IncludeSets.emitUsings(writer, protocolTraits.serdeUsings(FileKind.INITIAL_RESPONSE_SOURCE)); + IncludeSets.emitUsings(writer, ctx.protocolTraits().serdeUsings(FileKind.INITIAL_RESPONSE_SOURCE)); writer.write(""); // The serde impls are wrapped in an explicit namespace block (not a `using`), // matching C2J, which renders InitialResponse via the sub-object source template. - writer.writeNamespaceOpen("Aws"); - writer.writeNamespaceOpen(namespace); - writer.writeNamespaceOpen("Model"); + ModelFile.modelNamespace(writer, ctx.namespace(), () -> { writer.write(""); - protocolTraits.writeSerdeMethodImpls(writer, className); + ctx.protocolTraits().writeSerdeMethodImpls(writer, className); writer.write(""); // Delegate to the default ctor so all members are value-initialized before the // header-derived ones are set (matches C2J). writer.openBlock("$1L::$1L(const Http::HeaderValueCollection& responseHeaders) : $1L() {", "}", className, () -> writer.write("AWS_UNREFERENCED_PARAM(responseHeaders);")); writer.write(""); - writer.writeNamespaceClose("Model"); - writer.writeNamespaceClose(namespace); - writer.writeNamespaceClose("Aws"); + }); }); } @@ -537,40 +508,40 @@ private void renderEventStreamUnion(CppWriterDelegator writerDelegator, String o UnionShape union, List events, List exceptions) { String className = union.getId().getName(); - String errorType = namespace + "Error"; + String errorType = ctx.namespace() + "Error"; - String headerFile = "include/aws/" + smithyServiceName + "/model/" + className + ".h"; + String headerFile = "include/aws/" + ctx.smithyServiceName() + "/model/" + className + ".h"; writerDelegator.useFileWriter(headerFile, writer -> { writer.write("#pragma once"); - writer.write("#include ", smithyServiceName, namespace); + writer.write("#include ", ctx.smithyServiceName(), ctx.namespace()); // C2J omits the service Errors include: its header-include computation skips non-modeled // exception members (CppViewHelper: `if (next.isException() && !next.isModeledException()) // continue;`), which are the generic Error wrapper and resolve transitively. // Concrete event shapes AND modeled exceptions get their own model include. for (MemberShape event : events) { - writer.write("#include ", smithyServiceName, eventShapeName(event)); + writer.write("#include ", ctx.smithyServiceName(), eventShapeName(event)); } for (MemberShape exc : exceptions) { if (isModeledException(exc)) { - writer.write("#include ", smithyServiceName, exc.getTarget().getName()); + writer.write("#include ", ctx.smithyServiceName(), exc.getTarget().getName()); } } writer.write(""); writer.write("#include "); writer.write(""); - writer.writeNamespaceOpen("Aws"); - protocolTraits.writeShapeForwardDeclarations(writer); - writer.writeNamespaceOpen(namespace); - writer.writeNamespaceOpen("Model"); + writer.withNamespace("Aws", () -> { + ctx.protocolTraits().writeShapeForwardDeclarations(writer); + writer.withNamespace(ctx.namespace(), () -> + writer.withNamespace("Model", () -> { writer.write(""); - MemberRenderer.renderClassDocComment(writer, union, smithyServiceName, service.getVersion()); + MemberRenderer.renderClassDocComment(writer, union, ctx.smithyServiceName(), ctx.service().getVersion()); writer.openBlock("class $L {", "};", className, () -> { writer.write("public:"); - protocolTraits.writeSerdeMethodDecls(writer, exportMacro, className, null); + ctx.protocolTraits().writeSerdeMethodDecls(writer, ctx.exportMacro(), className, null); writer.write(""); // Event member accessors, typed as their concrete shape. for (MemberShape event : events) { - String cppType = CppTypeMapper.getCppType(model.expectShape(event.getTarget()), model); + String cppType = CppTypeMapper.getCppType(ctx.model().expectShape(event.getTarget()), ctx.model()); renderShapeAccessor(writer, className, cppType, event.getMemberName(), event); } // Exception member accessors: modeled -> concrete type; non-modeled -> Error. @@ -582,24 +553,23 @@ private void renderEventStreamUnion(CppWriterDelegator writerDelegator, String o writer.indent(); // Data members for (MemberShape event : events) { - String cppType = CppTypeMapper.getCppType(model.expectShape(event.getTarget()), model); - writer.write("$1L $2L;", cppType, "m_" + decapitalize(event.getMemberName())); + String cppType = CppTypeMapper.getCppType(ctx.model().expectShape(event.getTarget()), ctx.model()); + writer.write("$1L $2L;", cppType, CppNames.fieldName(event.getMemberName())); } for (MemberShape exc : exceptions) { - writer.write("$1L $2L;", exceptionType(exc, errorType), "m_" + decapitalize(exc.getMemberName())); + writer.write("$1L $2L;", exceptionType(exc, errorType), CppNames.fieldName(exc.getMemberName())); } // HasBeenSet flags for (MemberShape event : events) { - writer.write("bool $1LHasBeenSet = false;", "m_" + decapitalize(event.getMemberName())); + writer.write("bool $1LHasBeenSet = false;", CppNames.fieldName(event.getMemberName())); } for (MemberShape exc : exceptions) { - writer.write("bool $1LHasBeenSet = false;", "m_" + decapitalize(exc.getMemberName())); + writer.write("bool $1LHasBeenSet = false;", CppNames.fieldName(exc.getMemberName())); } }); writer.write(""); - writer.writeNamespaceClose("Model"); - writer.writeNamespaceClose(namespace); - writer.writeNamespaceClose("Aws"); + })); + }); }); // C2J generates the event stream union as a header-only type: the serde methods are @@ -615,8 +585,8 @@ private void renderEventStreamUnion(CppWriterDelegator writerDelegator, String o */ private void renderShapeAccessor(CppWriter writer, String className, String cppType, String memberName, MemberShape member) { - String getter = capitalize(memberName); - String field = "m_" + decapitalize(memberName); + String getter = CppNames.capitalize(memberName); + String field = CppNames.fieldName(memberName); String templateParam = getter + "T"; writer.write("///@{"); if (member.getTrait(DocumentationTrait.class).isPresent()) { @@ -639,13 +609,4 @@ private void renderShapeAccessor(CppWriter writer, String className, String cppT }); writer.write("///@}"); } - - private static String capitalize(String s) { - return s.substring(0, 1).toUpperCase() + s.substring(1); - } - - private static String decapitalize(String s) { - return s.substring(0, 1).toLowerCase() + s.substring(1); - } - } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSets.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSets.java index b567172be678..6b25f4427fc1 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSets.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSets.java @@ -83,6 +83,22 @@ static void emit(com.amazonaws.util.awsclientsmithygenerator.generators.CppWrite } } + /** + * Emits {@code #include } for each path, normalizing brackets so a caller may + * pass either {@code } or {@code aws/x/X.h}. Deduped and sorted CaseSensitive, + * matching {@link #emit}. This is the single place bracket policy for header includes lives. + */ + static void emitAngleIncludes(com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter writer, + java.util.Collection includePaths) { + java.util.TreeSet sorted = new java.util.TreeSet<>(); + for (String p : includePaths) { + sorted.add(p.replaceAll("^<|>$", "")); + } + for (String path : sorted) { + writer.write("#include <$L>", path); + } + } + /** Writes each namespace as {@code using namespace X;} in the given order (not sorted). */ static void emitUsings(com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter writer, List namespaces) { diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ModelFile.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ModelFile.java new file mode 100644 index 000000000000..3c5a94650729 --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ModelFile.java @@ -0,0 +1,24 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers; + +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; + +/** + * Emits the {@code Aws::::Model} nesting shared by every generated model + * file. Callers supply the class body; the triple open/close is owned here so it can + * never drift out of sync. Files that must interleave forward declarations between + * {@code Aws} and {@code } use {@link CppWriter#withNamespace} directly. + */ +final class ModelFile { + + private ModelFile() {} + + static void modelNamespace(CppWriter writer, String namespace, Runnable body) { + writer.withNamespace("Aws", () -> + writer.withNamespace(namespace, () -> + writer.withNamespace("Model", body))); + } +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/OutgoingEventStreamRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/OutgoingEventStreamRenderer.java index b01fcdf80b56..df03be05ff95 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/OutgoingEventStreamRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/OutgoingEventStreamRenderer.java @@ -6,13 +6,13 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.CppNames; import com.amazonaws.util.awsclientsmithygenerator.generators.model.CppTypeMapper; import com.amazonaws.util.awsclientsmithygenerator.generators.model.MemberRenderer; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.RenderContext; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeRenderer; import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.ProtocolTraits; -import software.amazon.smithy.model.Model; import software.amazon.smithy.model.shapes.MemberShape; -import software.amazon.smithy.model.shapes.ServiceShape; import software.amazon.smithy.model.shapes.Shape; import software.amazon.smithy.model.shapes.StructureShape; import software.amazon.smithy.model.shapes.UnionShape; @@ -38,23 +38,11 @@ public final class OutgoingEventStreamRenderer implements ShapeRenderer { private enum PayloadKind { BLOB, STRING, STRUCTURE, NONE } private final List outgoingEventStreams; - private final Model model; - private final ServiceShape service; - private final ProtocolTraits protocolTraits; - private final String namespace; - private final String exportMacro; - private final String smithyServiceName; + private final RenderContext ctx; - public OutgoingEventStreamRenderer(List outgoingEventStreams, Model model, ServiceShape service, - ProtocolTraits protocolTraits, String namespace, String exportMacro, - String smithyServiceName) { + public OutgoingEventStreamRenderer(List outgoingEventStreams, RenderContext ctx) { this.outgoingEventStreams = outgoingEventStreams; - this.model = model; - this.service = service; - this.protocolTraits = protocolTraits; - this.namespace = namespace; - this.exportMacro = exportMacro; - this.smithyServiceName = smithyServiceName; + this.ctx = ctx; } @Override @@ -66,30 +54,26 @@ public void render(CppWriterDelegator writerDelegator) { private void renderHeader(CppWriterDelegator writerDelegator, UnionShape union) { String className = CppTypeMapper.cppShapeName(union); - String fileName = "include/aws/" + smithyServiceName + "/model/" + className + ".h"; + String fileName = "include/aws/" + ctx.smithyServiceName() + "/model/" + className + ".h"; writerDelegator.useFileWriter(fileName, writer -> { writer.write("#pragma once"); java.util.Set includes = new java.util.TreeSet<>(); - includes.add(""); + includes.add(""); includes.add(""); includes.add(""); for (MemberShape event : union.getAllMembers().values()) { - includes.add(""); - } - for (String include : includes) { - writer.write("#include $L", include); + includes.add(""); } + IncludeSets.emitAngleIncludes(writer, includes); writer.write(""); writer.write("#include "); writer.write(""); - writer.writeNamespaceOpen("Aws"); - writer.writeNamespaceOpen(namespace); - writer.writeNamespaceOpen("Model"); + ModelFile.modelNamespace(writer, ctx.namespace(), () -> { writer.write(""); - MemberRenderer.renderClassDocComment(writer, union, smithyServiceName, service.getVersion()); + MemberRenderer.renderClassDocComment(writer, union, ctx.smithyServiceName(), ctx.service().getVersion()); writer.openBlock("class $L $L : public Aws::Utils::Event::EventEncoderStream {", "};", - exportMacro, className, () -> { + ctx.exportMacro(), className, () -> { writer.write("public:"); writer.write("$L() = default;", className); writer.write("explicit $L(std::shared_ptr streambuf)", @@ -100,9 +84,7 @@ private void renderHeader(CppWriterDelegator writerDelegator, UnionShape union) } }); writer.write(""); - writer.writeNamespaceClose("Model"); - writer.writeNamespaceClose(namespace); - writer.writeNamespaceClose("Aws"); + }); }); } @@ -110,13 +92,13 @@ private void renderHeader(CppWriterDelegator writerDelegator, UnionShape union) private void writeEventWriter(CppWriter writer, String className, MemberShape unionMember) { String eventShapeName = unionMember.getTarget().getName(); String wireKey = unionMember.getMemberName(); - StructureShape event = model.expectShape(unionMember.getTarget(), StructureShape.class); + StructureShape event = ctx.model().expectShape(unionMember.getTarget(), StructureShape.class); writer.openBlock("$L& Write$L(const $L& value) {", "}", className, eventShapeName, eventShapeName, () -> { writer.write("Aws::Utils::Event::Message msg;"); PayloadKind kind = payloadKind(event); switch (kind) { case BLOB: { - String getter = "value.Get" + capitalize(requirePayloadMember(event, kind)) + "()"; + String getter = "value.Get" + CppNames.capitalize(requirePayloadMember(event, kind)) + "()"; writer.openBlock("if (!$L.empty()) {", "}", getter, () -> { writeEventHeaders(writer, wireKey); writer.write("msg.InsertEventHeader(\":content-type\", Aws::String(\"application/octet-stream\"));"); @@ -127,11 +109,11 @@ private void writeEventWriter(CppWriter writer, String className, MemberShape un case STRING: writeEventHeaders(writer, wireKey); writer.write("msg.InsertEventHeader(\":content-type\", Aws::String(\"text/plain\"));"); - writer.write("msg.WriteEventPayload(value.Get$L());", capitalize(requirePayloadMember(event, kind))); + writer.write("msg.WriteEventPayload(value.Get$L());", CppNames.capitalize(requirePayloadMember(event, kind))); break; case STRUCTURE: writeEventHeaders(writer, wireKey); - protocolTraits.writeStructureEventPayload(writer, "msg", "value"); + ctx.protocolTraits().writeStructureEventPayload(writer, "msg", "value"); break; case NONE: default: @@ -164,7 +146,7 @@ private PayloadKind payloadKind(StructureShape event) { } if (nonHeader.size() == 1) { MemberShape member = nonHeader.get(0).getValue(); - Shape target = model.expectShape(member.getTarget()); + Shape target = ctx.model().expectShape(member.getTarget()); if (target.isStringShape()) { return PayloadKind.STRING; } @@ -190,8 +172,4 @@ private String requirePayloadMember(StructureShape event, PayloadKind kind) { .orElseThrow(() -> new IllegalStateException( "Event " + event.getId() + " classified as " + kind + " but has no payload member")); } - - private static String capitalize(String s) { - return s.isEmpty() ? s : Character.toUpperCase(s.charAt(0)) + s.substring(1); - } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java index 818f3d17b640..1ca457c227ab 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java @@ -6,21 +6,27 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.CppNames; import com.amazonaws.util.awsclientsmithygenerator.generators.model.CppTypeMapper; import com.amazonaws.util.awsclientsmithygenerator.generators.model.MemberRenderer; import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.FileKind; -import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.ProtocolTraits; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.RenderContext; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeClassifier; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeClassifier.RequestInfo; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeRenderer; -import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.node.BooleanNode; +import software.amazon.smithy.model.node.Node; +import software.amazon.smithy.model.node.NodeVisitor; +import software.amazon.smithy.model.node.StringNode; 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.StructureShape; +import software.amazon.smithy.model.traits.DocumentationTrait; import software.amazon.smithy.rulesengine.traits.ContextParamTrait; import software.amazon.smithy.rulesengine.traits.StaticContextParamsTrait; +import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -33,23 +39,11 @@ public final class RequestRenderer implements ShapeRenderer { private final List requests; - private final Model model; - private final ServiceShape service; - private final ProtocolTraits protocolTraits; - private final String namespace; - private final String exportMacro; - private final String smithyServiceName; - - public RequestRenderer(List requests, Model model, ServiceShape service, - ProtocolTraits protocolTraits, String namespace, String exportMacro, - String smithyServiceName) { + private final RenderContext ctx; + + public RequestRenderer(List requests, RenderContext ctx) { this.requests = requests; - this.model = model; - this.service = service; - this.protocolTraits = protocolTraits; - this.namespace = namespace; - this.exportMacro = exportMacro; - this.smithyServiceName = smithyServiceName; + this.ctx = ctx; } @Override @@ -68,17 +62,17 @@ private void renderHeader(CppWriterDelegator writerDelegator, // GetContentType/SetContentType, and emits no SerializePayload. Matching C2J: contentType // is stripped from the model entirely (affects includes AND rendering), while the payload // member stays for include computation but is skipped in accessor/private rendering. - boolean rawStreamingPayload = ShapeClassifier.isRawStreamingPayloadRequest(operation, model); + boolean rawStreamingPayload = ShapeClassifier.isRawStreamingPayloadRequest(operation, ctx.model()); // An event-stream (input) member targets a @streaming union: C2J renders it as a // std::shared_ptr with a collision-renamed getter and an inline empty // SerializePayload + GetBody() override, so it is excluded from the generic member path. - Optional eventStreamMember = ShapeClassifier.eventStreamMemberName(rawShape, model); + Optional eventStreamMember = ShapeClassifier.eventStreamMemberName(rawShape, ctx.model()); StructureShape includeShape = rawStreamingPayload ? shapeExcluding(rawShape, Set.of("contentType", "ContentType")) : rawShape; - Set genericExcluded = new java.util.HashSet<>(); + Set genericExcluded = new HashSet<>(); if (rawStreamingPayload) { // isRawStreamingPayloadRequest guarantees a payload member; absence is a codegen bug. - String payloadMember = ShapeClassifier.rawStreamingPayloadMemberName(rawShape, model) + String payloadMember = ShapeClassifier.rawStreamingPayloadMemberName(rawShape, ctx.model()) .orElseThrow(() -> new IllegalStateException( "Raw streaming payload request without a payload member: " + rawShape.getId())); genericExcluded.add("contentType"); @@ -87,25 +81,23 @@ private void renderHeader(CppWriterDelegator writerDelegator, } eventStreamMember.ifPresent(genericExcluded::add); StructureShape shape = genericExcluded.isEmpty() ? rawShape : shapeExcluding(rawShape, genericExcluded); - String fileName = "include/aws/" + smithyServiceName + "/model/" + className + ".h"; + String fileName = "include/aws/" + ctx.smithyServiceName() + "/model/" + className + ".h"; writerDelegator.useFileWriter(fileName, writer -> { writer.write("#pragma once"); Set includes = new TreeSet<>(); - includes.add(""); - includes.add(""); + includes.add(""); + includes.add(""); // NOTE: request headers do NOT include even when they // declare URI-taking methods (DumpBodyToUrl / AddQueryStringParameters). The // base AmazonWebServiceRequest.h forward-declares Aws::Http::URI, which is // sufficient for a reference parameter, and C2J relies on that forward decl. - List memberIncludes = CppTypeMapper.getIncludesForShape(includeShape, model, smithyServiceName); + List memberIncludes = CppTypeMapper.getIncludesForShape(includeShape, ctx.model(), ctx.smithyServiceName()); includes.addAll(memberIncludes); - for (String include : includes) { - writer.write("#include $L", include); - } + IncludeSets.emitAngleIncludes(writer, includes); boolean allPrimitive = shape.getAllMembers().values().stream() - .map(m -> model.expectShape(m.getTarget())) + .map(m -> ctx.model().expectShape(m.getTarget())) .allMatch(CppTypeMapper::isPrimitive); if (eventStreamMember.isPresent()) { // The event-stream member is stored as std::shared_ptr. @@ -117,27 +109,25 @@ private void renderHeader(CppWriterDelegator writerDelegator, writer.write("#include "); } - boolean streamingResponse = ShapeClassifier.isEventStreamResponseOperation(operation, model); - boolean streamingRequest = ShapeClassifier.isEventStreamRequestOperation(operation, model); + boolean streamingResponse = ShapeClassifier.isEventStreamResponseOperation(operation, ctx.model()); + boolean streamingRequest = ShapeClassifier.isEventStreamRequestOperation(operation, ctx.model()); if (streamingResponse) { writer.write("#include "); - writer.write("#include ", smithyServiceName, operation.getId().getName()); + writer.write("#include ", ctx.smithyServiceName(), operation.getId().getName()); } writer.write(""); - writer.writeNamespaceOpen("Aws"); - writer.writeNamespaceOpen(namespace); - writer.writeNamespaceOpen("Model"); + ModelFile.modelNamespace(writer, ctx.namespace(), () -> { writer.write(""); - MemberRenderer.renderClassDocComment(writer, shape, smithyServiceName, service.getVersion()); + MemberRenderer.renderClassDocComment(writer, shape, ctx.smithyServiceName(), ctx.service().getVersion()); // Raw-streaming-payload requests derive from StreamingRequest (a typedef for // AmazonStreamingWebServiceRequest declared in Request.h), matching C2J. - String baseClass = (rawStreamingPayload ? "Streaming" + namespace : namespace) + "Request"; + String baseClass = (rawStreamingPayload ? "Streaming" + ctx.namespace() : ctx.namespace()) + "Request"; writer.openBlock("class $L : public $L {", "};", className, baseClass, () -> { writer.write("public:"); - writer.write("$L $L() = default;", exportMacro, className); + writer.write("$L $L() = default;", ctx.exportMacro(), className); writer.write(""); writer.write("// Service request name is the Operation name which will send this request out,"); @@ -158,10 +148,10 @@ private void renderHeader(CppWriterDelegator writerDelegator, // SerializePayload is an inline no-op (matches C2J RequestHeader.vm). writer.write("// SerializePayload will not be invoked."); writer.write("// This request is sent by encoding its data in event-streams which is sent as IOStream via GetBody()"); - writer.write("$L Aws::String SerializePayload() const override { return {}; }", exportMacro); - writer.write("$L std::shared_ptr GetBody() const override;", exportMacro); + writer.write("$L Aws::String SerializePayload() const override { return {}; }", ctx.exportMacro()); + writer.write("$L std::shared_ptr GetBody() const override;", ctx.exportMacro()); } - protocolTraits.writeRequestMethodDecls(writer, exportMacro, shape, operation, model); + ctx.protocolTraits().writeRequestMethodDecls(writer, ctx.exportMacro(), shape, operation, ctx.model()); if (streamingResponse) { String handlerType = operation.getId().getName() + "Handler"; @@ -199,11 +189,11 @@ private void renderHeader(CppWriterDelegator writerDelegator, writer.write("/**"); writer.write(" * Helper function to collect parameters (configurable and static hardcoded) required for endpoint computation."); writer.write(" */"); - writer.write("$L EndpointParameters GetEndpointContextParams() const override;", exportMacro); + writer.write("$L EndpointParameters GetEndpointContextParams() const override;", ctx.exportMacro()); } writer.write(""); - MemberRenderer.renderPublicSection(writer, shape, model, exportMacro, className); + MemberRenderer.renderPublicSection(writer, shape, ctx.model(), ctx.exportMacro(), className); eventStreamMember.ifPresent(m -> renderEventStreamMemberAccessor(writer, className, rawShape, m)); @@ -215,33 +205,30 @@ private void renderHeader(CppWriterDelegator writerDelegator, if (streamingResponse) { // Mainline places the event-stream member, then the handler/decoder, after // the data members and before the HasBeenSet flags. - MemberRenderer.renderPrivateDataMembers(writer, shape, model); + MemberRenderer.renderPrivateDataMembers(writer, shape, ctx.model()); eventStreamMember.ifPresent(m -> writer.write("std::shared_ptr<$1L> m_$2L;", - eventStreamUnionType(rawShape, m), decapitalize(m))); + eventStreamUnionType(rawShape, m), CppNames.decapitalize(m))); String handlerType = operation.getId().getName() + "Handler"; writer.write("$1L m_handler;", handlerType); writer.write("Aws::Utils::Event::EventStreamDecoder m_decoder{Utils::Event::EventStreamDecoder(&m_handler)};"); writer.write(""); - MemberRenderer.renderPrivateHasBeenSetFlags(writer, shape, model); + MemberRenderer.renderPrivateHasBeenSetFlags(writer, shape, ctx.model()); eventStreamMember.ifPresent(m -> - writer.write("bool m_$1LHasBeenSet = false;", decapitalize(m))); + writer.write("bool m_$1LHasBeenSet = false;", CppNames.decapitalize(m))); } else { - MemberRenderer.renderPrivateSection(writer, shape, model); + MemberRenderer.renderPrivateSection(writer, shape, ctx.model()); } } }); writer.write(""); - - writer.writeNamespaceClose("Model"); - writer.writeNamespaceClose(namespace); - writer.writeNamespaceClose("Aws"); + }); }); } private void renderSource(CppWriterDelegator writerDelegator, StructureShape shape, OperationShape operation) { String className = operation.getId().getName() + "Request"; - Optional eventStreamMember = ShapeClassifier.eventStreamMemberName(shape, model); + Optional eventStreamMember = ShapeClassifier.eventStreamMemberName(shape, ctx.model()); String fileName = "source/model/" + className + ".cpp"; writerDelegator.useFileWriter(fileName, writer -> { @@ -250,28 +237,28 @@ private void renderSource(CppWriterDelegator writerDelegator, // it through StreamRequestSource.vm: AmazonWebServiceResult.h + the Stream/Utils/Aws // usings (not the JSON serde header/usings). The event-stream sub-case also defines // GetBody() returning its encoder member. - boolean streaming = ShapeClassifier.isRawStreamingPayloadRequest(operation, model) + boolean streaming = ShapeClassifier.isRawStreamingPayloadRequest(operation, ctx.model()) || eventStreamMember.isPresent(); if (streaming) { - List includes = new java.util.ArrayList<>( - IncludeSets.requestSourceBase(smithyServiceName, className)); + List includes = new ArrayList<>( + IncludeSets.requestSourceBase(ctx.smithyServiceName(), className)); includes.add("aws/core/AmazonWebServiceResult.h"); includes.add("utility"); - includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, model, smithyServiceName)); + includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, ctx.model(), ctx.smithyServiceName())); IncludeSets.emit(writer, includes); writer.write(""); - writer.write("using namespace Aws::$L::Model;", namespace); + writer.write("using namespace Aws::$L::Model;", ctx.namespace()); writer.write("using namespace Aws::Utils::Stream;"); writer.write("using namespace Aws::Utils;"); writer.write("using namespace Aws;"); writer.write(""); eventStreamMember.ifPresent(m -> { writer.write("std::shared_ptr $L::GetBody() const { return m_$L; }", - className, decapitalize(m)); + className, CppNames.decapitalize(m)); writer.write(""); }); // Header/query method bodies (SerializePayload is gated off for streaming requests). - protocolTraits.writeRequestMethodImpls(writer, className, shape, operation, service, model); + ctx.protocolTraits().writeRequestMethodImpls(writer, className, shape, operation, ctx.service(), ctx.model()); if (hasEndpointContextParams(operation, shape)) { writer.write(""); renderEndpointContextParams(writer, className, operation, shape); @@ -280,20 +267,20 @@ private void renderSource(CppWriterDelegator writerDelegator, return; } - List includes = new java.util.ArrayList<>( - IncludeSets.requestSourceBase(smithyServiceName, className)); - includes.addAll(protocolTraits.serdeIncludes(FileKind.REQUEST_SOURCE)); + List includes = new ArrayList<>( + IncludeSets.requestSourceBase(ctx.smithyServiceName(), className)); + includes.addAll(ctx.protocolTraits().serdeIncludes(FileKind.REQUEST_SOURCE)); // Serde-implementation includes derived from members (HashingUtils.h for blob Base64 // serde, AWSStringStream.h for header/query members), matching C2J computeSourceIncludes. - includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, model, smithyServiceName)); + includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, ctx.model(), ctx.smithyServiceName())); IncludeSets.emit(writer, includes); writer.write(""); - writer.write("using namespace Aws::$L::Model;", namespace); - IncludeSets.emitUsings(writer, protocolTraits.serdeUsings(FileKind.REQUEST_SOURCE)); + writer.write("using namespace Aws::$L::Model;", ctx.namespace()); + IncludeSets.emitUsings(writer, ctx.protocolTraits().serdeUsings(FileKind.REQUEST_SOURCE)); writer.write(""); - protocolTraits.writeRequestMethodImpls(writer, className, shape, operation, service, model); + ctx.protocolTraits().writeRequestMethodImpls(writer, className, shape, operation, ctx.service(), ctx.model()); if (hasEndpointContextParams(operation, shape)) { writer.write(""); @@ -331,37 +318,29 @@ private String eventStreamUnionType(StructureShape shape, String memberName) { private void renderEventStreamMemberAccessor(CppWriter writer, String className, StructureShape shape, String memberName) { String unionType = eventStreamUnionType(shape, memberName); - String cap = capitalize(memberName); - String field = "m_" + decapitalize(memberName); + String cap = CppNames.capitalize(memberName); + String field = CppNames.fieldName(memberName); String getter = cap.equals("Body") ? "GetMemberBody" : "Get" + cap; writer.write(""); writer.write("///@{"); MemberShape member = shape.getAllMembers().get(memberName); - if (member.getTrait(software.amazon.smithy.model.traits.DocumentationTrait.class).isPresent()) { + if (member.getTrait(DocumentationTrait.class).isPresent()) { MemberRenderer.writeDocComment(writer, MemberRenderer.collapseWhitespace( - member.getTrait(software.amazon.smithy.model.traits.DocumentationTrait.class).get().getValue())); + member.getTrait(DocumentationTrait.class).get().getValue())); } - writer.write("$1L std::shared_ptr<$2L> $3L() const { return $4L; }", exportMacro, unionType, getter, field); - writer.openBlock("$1L void Set$2L(const std::shared_ptr<$3L>& value) {", "}", exportMacro, cap, unionType, () -> { + writer.write("$1L std::shared_ptr<$2L> $3L() const { return $4L; }", ctx.exportMacro(), unionType, getter, field); + writer.openBlock("$1L void Set$2L(const std::shared_ptr<$3L>& value) {", "}", ctx.exportMacro(), cap, unionType, () -> { writer.write("$1LHasBeenSet = true;", field); writer.write("$1L = value;", field); }); writer.openBlock("$1L $2L& With$3L(const std::shared_ptr<$4L>& value) {", "}", - exportMacro, className, cap, unionType, () -> { + ctx.exportMacro(), className, cap, unionType, () -> { writer.write("Set$1L(value);", cap); writer.write("return *this;"); }); writer.write("///@}"); } - private static String capitalize(String s) { - return s.isEmpty() ? s : Character.toUpperCase(s.charAt(0)) + s.substring(1); - } - - private static String decapitalize(String s) { - return s.isEmpty() ? s : Character.toLowerCase(s.charAt(0)) + s.substring(1); - } - private boolean hasEndpointContextParams(OperationShape operation, StructureShape shape) { if (operation.hasTrait(StaticContextParamsTrait.class)) { return true; @@ -383,26 +362,8 @@ private void renderEndpointContextParams(CppWriter writer, String className, if (operation.hasTrait(StaticContextParamsTrait.class)) { writer.write("// Static context parameters"); StaticContextParamsTrait staticParams = operation.expectTrait(StaticContextParamsTrait.class); - staticParams.getParameters().forEach((name, def) -> { - def.getValue().accept(new software.amazon.smithy.model.node.NodeVisitor.Default() { - @Override - protected Void getDefault(software.amazon.smithy.model.node.Node node) { - return null; - } - @Override - public Void stringNode(software.amazon.smithy.model.node.StringNode node) { - writer.write("parameters.emplace_back(Aws::String(\"$L\"), \"$L\", Aws::Endpoint::EndpointParameter::ParameterOrigin::STATIC_CONTEXT);", - name, node.getValue()); - return null; - } - @Override - public Void booleanNode(software.amazon.smithy.model.node.BooleanNode node) { - writer.write("parameters.emplace_back(Aws::String(\"$L\"), $L, Aws::Endpoint::EndpointParameter::ParameterOrigin::STATIC_CONTEXT);", - name, node.getValue()); - return null; - } - }); - }); + staticParams.getParameters().forEach((name, def) -> + appendStaticContextParam(writer, name, def.getValue())); } boolean hasContextParams = shape.getAllMembers().values().stream() @@ -415,7 +376,7 @@ public Void booleanNode(software.amazon.smithy.model.node.BooleanNode node) { ContextParamTrait contextParam = member.expectTrait(ContextParamTrait.class); String paramName = contextParam.getName(); String memberName = entry.getKey(); - String capitalizedMember = memberName.substring(0, 1).toUpperCase() + memberName.substring(1); + String capitalizedMember = CppNames.capitalize(memberName); writer.openBlock("if ($LHasBeenSet()) {", "}", capitalizedMember, () -> { writer.write("parameters.emplace_back(Aws::String(\"$L\"), this->Get$L(), Aws::Endpoint::EndpointParameter::ParameterOrigin::OPERATION_CONTEXT);", paramName, capitalizedMember); @@ -428,4 +389,25 @@ public Void booleanNode(software.amazon.smithy.model.node.BooleanNode node) { }); } + private void appendStaticContextParam(CppWriter writer, String name, Node value) { + value.accept(new NodeVisitor.Default() { + @Override + protected Void getDefault(Node node) { + return null; + } + @Override + public Void stringNode(StringNode node) { + writer.write("parameters.emplace_back(Aws::String(\"$L\"), \"$L\", Aws::Endpoint::EndpointParameter::ParameterOrigin::STATIC_CONTEXT);", + name, node.getValue()); + return null; + } + @Override + public Void booleanNode(BooleanNode node) { + writer.write("parameters.emplace_back(Aws::String(\"$L\"), $L, Aws::Endpoint::EndpointParameter::ParameterOrigin::STATIC_CONTEXT);", + name, node.getValue()); + return null; + } + }); + } + } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ResultRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ResultRenderer.java index b63b2366c6c5..39b981fbaa1c 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ResultRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ResultRenderer.java @@ -5,16 +5,15 @@ package com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers; import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.CppNames; import com.amazonaws.util.awsclientsmithygenerator.generators.model.CppTypeMapper; import com.amazonaws.util.awsclientsmithygenerator.generators.model.MemberRenderer; import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.FileKind; -import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.ProtocolTraits; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.RenderContext; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeClassifier.ResultInfo; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeRenderer; -import software.amazon.smithy.model.Model; 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.StructureShape; import software.amazon.smithy.model.traits.DocumentationTrait; import software.amazon.smithy.model.traits.HttpPayloadTrait; @@ -28,23 +27,11 @@ public final class ResultRenderer implements ShapeRenderer { private final List results; - private final Model model; - private final ServiceShape service; - private final ProtocolTraits protocolTraits; - private final String namespace; - private final String exportMacro; - private final String smithyServiceName; - - public ResultRenderer(List results, Model model, ServiceShape service, - ProtocolTraits protocolTraits, String namespace, String exportMacro, - String smithyServiceName) { + private final RenderContext ctx; + + public ResultRenderer(List results, RenderContext ctx) { this.results = results; - this.model = model; - this.service = service; - this.protocolTraits = protocolTraits; - this.namespace = namespace; - this.exportMacro = exportMacro; - this.smithyServiceName = smithyServiceName; + this.ctx = ctx; } @Override @@ -60,88 +47,69 @@ public void render(CppWriterDelegator writerDelegator) { } } - /** Returns the name of the {@code @httpPayload} streaming member, or null if none. */ + /** + * The name of the {@code @httpPayload} streaming member. Only called for results the + * classifier already flagged as streaming, so a missing payload member is a codegen bug + * rather than a modeled state — fail fast instead of returning null. + */ private String streamingPayloadMemberName(StructureShape shape) { for (Map.Entry entry : shape.getAllMembers().entrySet()) { if (entry.getValue().hasTrait(HttpPayloadTrait.class)) { return entry.getKey(); } } - return null; - } - - /** {@code m_} + decapitalized member name, e.g. "AudioStream" -> "m_audioStream". */ - private static String fieldName(String memberName) { - return "m_" + Character.toLowerCase(memberName.charAt(0)) + memberName.substring(1); - } - - /** Capitalized member name for accessor methods, e.g. "audioStream" -> "AudioStream". */ - private static String capitalize(String memberName) { - return Character.toUpperCase(memberName.charAt(0)) + memberName.substring(1); + throw new IllegalStateException( + "Streaming result " + shape.getId() + " has no @httpPayload member"); } private void renderHeader(CppWriterDelegator writerDelegator, StructureShape shape, OperationShape operation) { String className = operation.getId().getName() + "Result"; - String fileName = "include/aws/" + smithyServiceName + "/model/" + className + ".h"; + String fileName = "include/aws/" + ctx.smithyServiceName() + "/model/" + className + ".h"; writerDelegator.useFileWriter(fileName, writer -> { writer.write("#pragma once"); // AWSString.h is only needed for the top-level m_requestId; string-typed members // bring their own include via getIncludesForShape. Matches C2J include hygiene. List includes = new java.util.ArrayList<>(IncludeSets.resultHeaderBase( - smithyServiceName, namespace, protocolTraits.resultHasTopLevelRequestId())); - for (String memberInc : CppTypeMapper.getIncludesForShape(shape, model, smithyServiceName)) { - includes.add(memberInc.replaceAll("^<|>$", "")); + ctx.smithyServiceName(), ctx.namespace(), ctx.protocolTraits().resultHasTopLevelRequestId())); + for (String memberInc : CppTypeMapper.getIncludesForShape(shape, ctx.model(), ctx.smithyServiceName())) { + includes.add(memberInc); } // Protocols whose result-header serde types are named in the class signature (CBOR: // CborValue) add their own header here; JSON/XML forward-declare and add nothing. - includes.addAll(protocolTraits.serdeIncludes(FileKind.RESULT_HEADER)); - IncludeSets.emit(writer, includes); + includes.addAll(ctx.protocolTraits().serdeIncludes(FileKind.RESULT_HEADER)); + IncludeSets.emitAngleIncludes(writer, includes); writer.write(""); writer.write("#include "); writer.write(""); - writer.writeNamespaceOpen("Aws"); + writer.withNamespace("Aws", () -> { writer.write("template "); writer.write("class AmazonWebServiceResult;"); writer.write(""); - protocolTraits.writeResultForwardDeclarations(writer); + ctx.protocolTraits().writeResultForwardDeclarations(writer); - writer.writeNamespaceOpen(namespace); - writer.writeNamespaceOpen("Model"); + writer.withNamespace(ctx.namespace(), () -> + writer.withNamespace("Model", () -> { if (shape.getTrait(DocumentationTrait.class).isPresent()) { - MemberRenderer.renderClassDocComment(writer, shape, smithyServiceName, service.getVersion()); + MemberRenderer.renderClassDocComment(writer, shape, ctx.smithyServiceName(), ctx.service().getVersion()); } writer.openBlock("class $L {", "};", className, () -> { writer.write("public:"); - writer.write("$L $L() = default;", exportMacro, className); - protocolTraits.writeResultSerdeDecls(writer, exportMacro, className); + writer.write("$L $L() = default;", ctx.exportMacro(), className); + ctx.protocolTraits().writeResultSerdeDecls(writer, ctx.exportMacro(), className); writer.write(""); - MemberRenderer.renderPublicSectionForResult(writer, shape, model, exportMacro, className, - protocolTraits.widensIntegers()); + MemberRenderer.renderPublicSectionForResult(writer, shape, ctx.model(), ctx.exportMacro(), className, + ctx.protocolTraits().widensIntegers()); - boolean topLevelRequestId = protocolTraits.resultHasTopLevelRequestId(); + boolean topLevelRequestId = ctx.protocolTraits().resultHasTopLevelRequestId(); if (topLevelRequestId) { - writer.write(""); - writer.write("///@{"); - writer.write(""); - writer.write("inline const Aws::String& GetRequestId() const { return m_requestId; }"); - writer.write("template "); - writer.openBlock("void SetRequestId(RequestIdT&& value) {", "}", () -> { - writer.write("m_requestIdHasBeenSet = true;"); - writer.write("m_requestId = std::forward(value);"); - }); - writer.write("template "); - writer.openBlock("$L& WithRequestId(RequestIdT&& value) {", "}", className, () -> { - writer.write("SetRequestId(std::forward(value));"); - writer.write("return *this;"); - }); - writer.write("///@}"); + MemberRenderer.renderRequestIdAccessors(writer, className); } writer.write("inline Aws::Http::HttpResponseCode GetHttpResponseCode() const { return m_HttpResponseCode; }"); @@ -150,7 +118,7 @@ private void renderHeader(CppWriterDelegator writerDelegator, writer.dedent(); writer.write("private:"); writer.indent(); - MemberRenderer.renderPrivateDataMembers(writer, shape, model, protocolTraits.widensIntegers()); + MemberRenderer.renderPrivateDataMembers(writer, shape, ctx.model(), ctx.protocolTraits().widensIntegers()); if (topLevelRequestId) { // The blank line separates the modeled members from the m_requestId group; // C2J omits it (and m_requestId) for Query/EC2 results. @@ -158,16 +126,14 @@ private void renderHeader(CppWriterDelegator writerDelegator, writer.write("Aws::String m_requestId;"); } writer.write("Aws::Http::HttpResponseCode m_HttpResponseCode;"); - MemberRenderer.renderPrivateHasBeenSetFlags(writer, shape, model); + MemberRenderer.renderPrivateHasBeenSetFlags(writer, shape, ctx.model()); if (topLevelRequestId) { writer.write("bool m_requestIdHasBeenSet = false;"); } }); writer.write(""); - - writer.writeNamespaceClose("Model"); - writer.writeNamespaceClose(namespace); - writer.writeNamespaceClose("Aws"); + })); + }); }); } @@ -178,19 +144,19 @@ private void renderSource(CppWriterDelegator writerDelegator, writerDelegator.useFileWriter(fileName, writer -> { List includes = new java.util.ArrayList<>( - IncludeSets.resultSourceBase(smithyServiceName, className)); - includes.addAll(protocolTraits.serdeIncludes(FileKind.RESULT_SOURCE)); + IncludeSets.resultSourceBase(ctx.smithyServiceName(), className)); + includes.addAll(ctx.protocolTraits().serdeIncludes(FileKind.RESULT_SOURCE)); // Serde-implementation includes derived from members (HashingUtils.h for blob Base64 // serde, AWSStringStream.h for header/query members), matching C2J computeSourceIncludes. - includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, model, smithyServiceName)); + includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, ctx.model(), ctx.smithyServiceName())); IncludeSets.emit(writer, includes); writer.write(""); - writer.write("using namespace Aws::$L::Model;", namespace); - IncludeSets.emitUsings(writer, protocolTraits.serdeUsings(FileKind.RESULT_SOURCE)); + writer.write("using namespace Aws::$L::Model;", ctx.namespace()); + IncludeSets.emitUsings(writer, ctx.protocolTraits().serdeUsings(FileKind.RESULT_SOURCE)); writer.write("using namespace Aws;"); writer.write(""); - protocolTraits.writeResultSerdeImpls(writer, className, shape, model, namespace); + ctx.protocolTraits().writeResultSerdeImpls(writer, className, shape, ctx.model(), ctx.namespace()); writer.write(""); }); } @@ -204,82 +170,68 @@ private void renderStreamingHeader(CppWriterDelegator writerDelegator, StructureShape shape, OperationShape operation) { String className = operation.getId().getName() + "Result"; String streamMember = streamingPayloadMemberName(shape); - String fileName = "include/aws/" + smithyServiceName + "/model/" + className + ".h"; + String fileName = "include/aws/" + ctx.smithyServiceName() + "/model/" + className + ".h"; writerDelegator.useFileWriter(fileName, writer -> { writer.write("#pragma once"); List includes = new java.util.ArrayList<>( - IncludeSets.streamingResultHeaderBase(smithyServiceName, namespace)); - for (String memberInc : CppTypeMapper.getIncludesForShape(shape, model, smithyServiceName)) { - includes.add(memberInc.replaceAll("^<|>$", "")); + IncludeSets.streamingResultHeaderBase(ctx.smithyServiceName(), ctx.namespace())); + for (String memberInc : CppTypeMapper.getIncludesForShape(shape, ctx.model(), ctx.smithyServiceName())) { + includes.add(memberInc); } - IncludeSets.emit(writer, includes); + IncludeSets.emitAngleIncludes(writer, includes); writer.write(""); writer.write("#include "); writer.write(""); - writer.writeNamespaceOpen("Aws"); + writer.withNamespace("Aws", () -> { writer.write("template "); writer.write("class AmazonWebServiceResult;"); writer.write(""); - writer.writeNamespaceOpen(namespace); - writer.writeNamespaceOpen("Model"); + writer.withNamespace(ctx.namespace(), () -> + writer.withNamespace("Model", () -> { if (shape.getTrait(DocumentationTrait.class).isPresent()) { - MemberRenderer.renderClassDocComment(writer, shape, smithyServiceName, service.getVersion()); + MemberRenderer.renderClassDocComment(writer, shape, ctx.smithyServiceName(), ctx.service().getVersion()); } writer.openBlock("class $L {", "};", className, () -> { writer.write("public:"); - writer.write("$L $L() = default;", exportMacro, className); - writer.write("$L $L($L&&) = default;", exportMacro, className, className); - writer.write("$L $L& operator=($L&&) = default;", exportMacro, className, className); + writer.write("$L $L() = default;", ctx.exportMacro(), className); + writer.write("$L $L($L&&) = default;", ctx.exportMacro(), className, className); + writer.write("$L $L& operator=($L&&) = default;", ctx.exportMacro(), className, className); writer.write("// we delete these because Microsoft doesn't handle move generation correctly"); writer.write("// and we therefore don't trust them to get it right here either."); writer.write("$L(const $L&) = delete;", className, className); writer.write("$L& operator=(const $L&) = delete;", className, className); writer.write(""); writer.write("$L $L(Aws::AmazonWebServiceResult&& result);", - exportMacro, className); + ctx.exportMacro(), className); writer.write("$L $L& operator=(Aws::AmazonWebServiceResult&& result);", - exportMacro, className); + ctx.exportMacro(), className); writer.write(""); // Streaming payload accessors (no Set/With/HasBeenSet for the stream member). // The getter is named after the member (GetBody, GetAudioStream, GetResponse); // ReplaceBody stays literal, matching C2J StreamResultHeader.vm. - String streamField = fieldName(streamMember); + String streamField = CppNames.fieldName(streamMember); writer.write("///@{"); shape.getMember(streamMember) .flatMap(m -> m.getTrait(DocumentationTrait.class)) .ifPresent(doc -> MemberRenderer.writeDocComment(writer, MemberRenderer.collapseWhitespace(doc.getValue()))); writer.write("inline Aws::IOStream& Get$L() const { return $L.GetUnderlyingStream(); }", - capitalize(streamMember), streamField); + CppNames.capitalize(streamMember), streamField); writer.write("inline void ReplaceBody(Aws::IOStream* body) { " + "$L = Aws::Utils::Stream::ResponseStream(body); }", streamField); writer.write("///@}"); - MemberRenderer.renderPublicSectionForResultExcluding(writer, shape, model, exportMacro, - className, streamMember, protocolTraits.widensIntegers()); + MemberRenderer.renderPublicSectionForResultExcluding(writer, shape, ctx.model(), ctx.exportMacro(), + className, streamMember, ctx.protocolTraits().widensIntegers()); - writer.write(""); - writer.write("///@{"); - writer.write(""); - writer.write("inline const Aws::String& GetRequestId() const { return m_requestId; }"); - writer.write("template "); - writer.openBlock("void SetRequestId(RequestIdT&& value) {", "}", () -> { - writer.write("m_requestIdHasBeenSet = true;"); - writer.write("m_requestId = std::forward(value);"); - }); - writer.write("template "); - writer.openBlock("$L& WithRequestId(RequestIdT&& value) {", "}", className, () -> { - writer.write("SetRequestId(std::forward(value));"); - writer.write("return *this;"); - }); - writer.write("///@}"); + MemberRenderer.renderRequestIdAccessors(writer, className); writer.write("inline Aws::Http::HttpResponseCode GetHttpResponseCode() const { return m_HttpResponseCode; }"); writer.write(""); @@ -288,20 +240,18 @@ private void renderStreamingHeader(CppWriterDelegator writerDelegator, writer.write("private:"); writer.indent(); writer.write("Aws::Utils::Stream::ResponseStream $L{};", streamField); - MemberRenderer.renderPrivateDataMembersExcluding(writer, shape, model, streamMember, - protocolTraits.widensIntegers()); + MemberRenderer.renderPrivateDataMembersExcluding(writer, shape, ctx.model(), streamMember, + ctx.protocolTraits().widensIntegers()); writer.write(""); writer.write("Aws::String m_requestId;"); writer.write("Aws::Http::HttpResponseCode m_HttpResponseCode;"); writer.write("bool $LHasBeenSet = false;", streamField); - MemberRenderer.renderPrivateHasBeenSetFlagsExcluding(writer, shape, model, streamMember); + MemberRenderer.renderPrivateHasBeenSetFlagsExcluding(writer, shape, ctx.model(), streamMember); writer.write("bool m_requestIdHasBeenSet = false;"); }); writer.write(""); - - writer.writeNamespaceClose("Model"); - writer.writeNamespaceClose(namespace); - writer.writeNamespaceClose("Aws"); + })); + }); }); } @@ -312,18 +262,18 @@ private void renderStreamingHeader(CppWriterDelegator writerDelegator, private void renderStreamingSource(CppWriterDelegator writerDelegator, StructureShape shape, OperationShape operation) { String className = operation.getId().getName() + "Result"; - String streamField = fieldName(streamingPayloadMemberName(shape)); + String streamField = CppNames.fieldName(streamingPayloadMemberName(shape)); String fileName = "source/model/" + className + ".cpp"; writerDelegator.useFileWriter(fileName, writer -> { List includes = new java.util.ArrayList<>( - IncludeSets.streamingResultSourceBase(smithyServiceName, className)); - includes.addAll(protocolTraits.serdeIncludes(FileKind.STREAMING_RESULT_SOURCE)); + IncludeSets.streamingResultSourceBase(ctx.smithyServiceName(), className)); + includes.addAll(ctx.protocolTraits().serdeIncludes(FileKind.STREAMING_RESULT_SOURCE)); // Serde-implementation includes derived from members (e.g. HashingUtils.h for the // blob payload member's Base64 serde), matching C2J computeSourceIncludes. - includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, model, smithyServiceName)); + includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, ctx.model(), ctx.smithyServiceName())); IncludeSets.emit(writer, includes); writer.write(""); - writer.write("using namespace Aws::$L::Model;", namespace); + writer.write("using namespace Aws::$L::Model;", ctx.namespace()); writer.write("using namespace Aws::Utils::Stream;"); writer.write("using namespace Aws::Utils;"); writer.write("using namespace Aws;"); @@ -338,7 +288,7 @@ private void renderStreamingSource(CppWriterDelegator writerDelegator, writer.write("$L = result.TakeOwnershipOfPayload();", streamField); writer.write("$LHasBeenSet = true;", streamField); writer.write("// TODO: header-bound member deserialization"); - protocolTraits.writeResultStatusCodeMembers(writer, shape, model); + ctx.protocolTraits().writeResultStatusCodeMembers(writer, shape, ctx.model()); writer.write("return *this;"); }); writer.write(""); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/SubObjectRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/SubObjectRenderer.java index 571d7d1f4228..76d2ddcf95b5 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/SubObjectRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/SubObjectRenderer.java @@ -9,10 +9,8 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.model.CppTypeMapper; import com.amazonaws.util.awsclientsmithygenerator.generators.model.MemberRenderer; import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.FileKind; -import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.ProtocolTraits; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.RenderContext; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeRenderer; -import software.amazon.smithy.model.Model; -import software.amazon.smithy.model.shapes.ServiceShape; import software.amazon.smithy.model.shapes.Shape; import software.amazon.smithy.model.traits.StreamingTrait; @@ -24,25 +22,11 @@ public final class SubObjectRenderer implements ShapeRenderer { private final List subObjects; - private final Model model; - private final ServiceShape service; - private final ProtocolTraits protocolTraits; - private final String namespace; - private final String exportMacro; - private final String serviceName; - private final String smithyServiceName; - - public SubObjectRenderer(List subObjects, Model model, ServiceShape service, - ProtocolTraits protocolTraits, String namespace, String exportMacro, - String serviceName, String smithyServiceName) { + private final RenderContext ctx; + + public SubObjectRenderer(List subObjects, RenderContext ctx) { this.subObjects = subObjects; - this.model = model; - this.service = service; - this.protocolTraits = protocolTraits; - this.namespace = namespace; - this.exportMacro = exportMacro; - this.serviceName = serviceName; - this.smithyServiceName = smithyServiceName; + this.ctx = ctx; } @Override @@ -63,21 +47,21 @@ public void render(CppWriterDelegator writerDelegator) { private void renderHeader(CppWriterDelegator writerDelegator, Shape shape) { String className = CppTypeMapper.cppShapeName(shape); - String fileName = "include/aws/" + smithyServiceName + "/model/" + className + ".h"; + String fileName = "include/aws/" + ctx.smithyServiceName() + "/model/" + className + ".h"; writerDelegator.useFileWriter(fileName, writer -> { writer.write("#pragma once"); // Includes List includes = new java.util.ArrayList<>(); - includes.add("aws/" + smithyServiceName + "/" + namespace + "_EXPORTS.h"); - for (String memberInc : CppTypeMapper.getIncludesForShape(shape, model, smithyServiceName)) { - includes.add(memberInc.replaceAll("^<|>$", "")); + includes.add("aws/" + ctx.smithyServiceName() + "/" + ctx.namespace() + "_EXPORTS.h"); + for (String memberInc : CppTypeMapper.getIncludesForShape(shape, ctx.model(), ctx.smithyServiceName())) { + includes.add(memberInc); } - includes.addAll(protocolTraits.serdeIncludes(FileKind.SUBOBJECT_HEADER)); - IncludeSets.emit(writer, includes); + includes.addAll(ctx.protocolTraits().serdeIncludes(FileKind.SUBOBJECT_HEADER)); + IncludeSets.emitAngleIncludes(writer, includes); boolean allPrimitive = shape.getAllMembers().values().stream() - .map(m -> model.expectShape(m.getTarget())) + .map(m -> ctx.model().expectShape(m.getTarget())) .allMatch(CppTypeMapper::isPrimitive); if (!allPrimitive) { writer.write(""); @@ -85,35 +69,33 @@ private void renderHeader(CppWriterDelegator writerDelegator, Shape shape) { } writer.write(""); - writer.writeNamespaceOpen("Aws"); - protocolTraits.writeShapeForwardDeclarations(writer); - writer.writeNamespaceOpen(namespace); - writer.writeNamespaceOpen("Model"); + writer.withNamespace("Aws", () -> { + ctx.protocolTraits().writeShapeForwardDeclarations(writer); + writer.withNamespace(ctx.namespace(), () -> + writer.withNamespace("Model", () -> { writer.write(""); - MemberRenderer.renderClassDocComment(writer, shape, smithyServiceName, service.getVersion()); + MemberRenderer.renderClassDocComment(writer, shape, ctx.smithyServiceName(), ctx.service().getVersion()); writer.openBlock("class $L {", "};", className, () -> { writer.write("public:"); - protocolTraits.writeSerdeMethodDecls(writer, exportMacro, className, null); + ctx.protocolTraits().writeSerdeMethodDecls(writer, ctx.exportMacro(), className, null); // A memberless shape ends right after its serde decls: C2J emits no accessors // and no private: section (ModelClassMembersAndInlines.vm gates both on // $shape.members.size() > 0). if (!shape.getAllMembers().isEmpty()) { - boolean wideIntegers = protocolTraits.widensIntegers(); + boolean wideIntegers = ctx.protocolTraits().widensIntegers(); writer.write(""); - MemberRenderer.renderPublicSection(writer, shape, model, exportMacro, className, wideIntegers); + MemberRenderer.renderPublicSection(writer, shape, ctx.model(), ctx.exportMacro(), className, wideIntegers); writer.dedent(); writer.write("private:"); writer.indent(); - MemberRenderer.renderPrivateSection(writer, shape, model, wideIntegers); + MemberRenderer.renderPrivateSection(writer, shape, ctx.model(), wideIntegers); } }); writer.write(""); - - writer.writeNamespaceClose("Model"); - writer.writeNamespaceClose(namespace); - writer.writeNamespaceClose("Aws"); + })); + }); }); } @@ -123,28 +105,23 @@ private void renderSource(CppWriterDelegator writerDelegator, Shape shape) { writerDelegator.useFileWriter(fileName, writer -> { List includes = new java.util.ArrayList<>( - IncludeSets.subObjectSourceBase(smithyServiceName, className)); - includes.addAll(protocolTraits.serdeIncludes(FileKind.SUBOBJECT_SOURCE)); + IncludeSets.subObjectSourceBase(ctx.smithyServiceName(), className)); + includes.addAll(ctx.protocolTraits().serdeIncludes(FileKind.SUBOBJECT_SOURCE)); // Serde-implementation includes derived from members (e.g. HashingUtils.h for blob // Base64 serde), matching C2J's computeSourceIncludes. - includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, model, smithyServiceName)); + includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, ctx.model(), ctx.smithyServiceName())); IncludeSets.emit(writer, includes); writer.write(""); - IncludeSets.emitUsings(writer, protocolTraits.serdeUsings(FileKind.SUBOBJECT_SOURCE)); + IncludeSets.emitUsings(writer, ctx.protocolTraits().serdeUsings(FileKind.SUBOBJECT_SOURCE)); writer.write(""); - writer.writeNamespaceOpen("Aws"); - writer.writeNamespaceOpen(namespace); - writer.writeNamespaceOpen("Model"); + ModelFile.modelNamespace(writer, ctx.namespace(), () -> { writer.write(""); - protocolTraits.writeSerdeMethodImpls(writer, className); + ctx.protocolTraits().writeSerdeMethodImpls(writer, className); writer.write(""); - - writer.writeNamespaceClose("Model"); - writer.writeNamespaceClose(namespace); - writer.writeNamespaceClose("Aws"); + }); }); } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/transforms/GlobalTransforms.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/transforms/GlobalTransforms.java index fc11b5373dd7..75f5c85f16e3 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/transforms/GlobalTransforms.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/transforms/GlobalTransforms.java @@ -51,6 +51,11 @@ public final class GlobalTransforms { private GlobalTransforms() {} + // NOTE: This reserved-member rename is intentionally NOT wired into the transform + // pipeline yet. It encodes a known C2J-parity requirement (body -> requestBody, + // headers -> headerValues) that is validated by GlobalTransformsTest but not applied + // during generation. Do not delete it and do not hook it up as part of a cleanup pass — + // wiring it in changes generated output and must be its own reviewed change. /** * Returns the renamed C++ member name if this member is reserved. * Only applies to request shape members (caller must filter). diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriterTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriterTest.java new file mode 100644 index 000000000000..d8c0956a697d --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriterTest.java @@ -0,0 +1,24 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class CppWriterTest { + @Test + void withNamespace_wrapsBodyInMatchingOpenAndClose() { + CppWriter plain = new CppWriter(); + plain.writeNamespaceOpen("Aws"); + plain.write("int x = 1;"); + plain.writeNamespaceClose("Aws"); + + CppWriter scoped = new CppWriter(); + scoped.withNamespace("Aws", () -> scoped.write("int x = 1;")); + + assertEquals(plain.toString(), scoped.toString()); + } +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppNamesTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppNamesTest.java new file mode 100644 index 000000000000..be9b2915caa9 --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppNamesTest.java @@ -0,0 +1,30 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class CppNamesTest { + @Test + void capitalize_upsFirstChar() { + assertEquals("AudioStream", CppNames.capitalize("audioStream")); + assertEquals("", CppNames.capitalize("")); + assertEquals("X", CppNames.capitalize("x")); + } + + @Test + void decapitalize_downsFirstChar() { + assertEquals("audioStream", CppNames.decapitalize("AudioStream")); + assertEquals("", CppNames.decapitalize("")); + } + + @Test + void fieldName_prefixesMUnderscoreAndDecapitalizes() { + assertEquals("m_audioStream", CppNames.fieldName("AudioStream")); + assertEquals("m_shardId", CppNames.fieldName("shardId")); + } +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/EventStreamRendererTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/EventStreamRendererTest.java index ac4ba86ffc0f..f3638429c042 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/EventStreamRendererTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/EventStreamRendererTest.java @@ -6,6 +6,7 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.RenderContext; import com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers.EventStreamRenderer; import org.junit.jupiter.api.Test; import software.amazon.smithy.build.MockManifest; @@ -94,8 +95,8 @@ private static String render(String fileSuffix) { Protocol protocol = ProtocolResolver.resolve(service, model); EventStreamRenderer renderer = new EventStreamRenderer( ShapeClassifier.classify(model, service, protocol).eventStreamHandlers(), - model, service, ProtocolResolver.traitsFor(protocol), - "Example", "AWS_EXAMPLE_API", "example"); + new RenderContext(model, service, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example")); renderer.render(delegator); delegator.flushWriters(); return manifest.getFileString( diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererTest.java index 0079791158a7..8699f0ad7be2 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererTest.java @@ -377,4 +377,46 @@ void renderPrivateSection_hasBeenSetFlagsGroupedAtEnd() { assertTrue(nameFieldPos < nameHasBeenSetPos, "Data members should precede HasBeenSet flags"); assertTrue(countFieldPos < countHasBeenSetPos, "Data members should precede HasBeenSet flags"); } + + @Test + void renderRequestIdAccessors_emitsTemplatedGetSetWith() { + com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter writer = + new com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter(); + MemberRenderer.renderRequestIdAccessors(writer, "GetFooResult"); + String out = writer.toString(); + assertTrue(out.contains("inline const Aws::String& GetRequestId() const { return m_requestId; }")); + assertTrue(out.contains("template ")); + assertTrue(out.contains("void SetRequestId(RequestIdT&& value)")); + assertTrue(out.contains("m_requestIdHasBeenSet = true;")); + assertTrue(out.contains("m_requestId = std::forward(value);")); + assertTrue(out.contains("GetFooResult& WithRequestId(RequestIdT&& value)")); + assertTrue(out.contains("SetRequestId(std::forward(value));")); + assertTrue(out.contains("///@{")); + assertTrue(out.contains("///@}")); + } + + @Test + void render_withOptions_matchesRenderPublicSection() { + // Build the same shape twice and assert the options-object path equals the legacy path. + software.amazon.smithy.model.shapes.StringShape str = + software.amazon.smithy.model.shapes.StringShape.builder().id("com.example#String").build(); + software.amazon.smithy.model.shapes.StructureShape shape = + software.amazon.smithy.model.shapes.StructureShape.builder() + .id("com.example#Foo") + .addMember("ShardId", str.getId()) + .build(); + software.amazon.smithy.model.Model model = + software.amazon.smithy.model.Model.builder().addShapes(str, shape).build(); + + com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter legacy = + new com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter(); + MemberRenderer.renderPublicSection(legacy, shape, model, "AWS_EXAMPLE_API", "Foo"); + + com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter viaOpts = + new com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter(); + MemberRenderer.render(viaOpts, shape, model, + new MemberOptions().exportMacro("AWS_EXAMPLE_API").className("Foo").emitHasBeenSet(true)); + + assertEquals(legacy.toString(), viaOpts.toString()); + } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/OutgoingEventStreamRendererTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/OutgoingEventStreamRendererTest.java index f681d9b48550..483d2f652a20 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/OutgoingEventStreamRendererTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/OutgoingEventStreamRendererTest.java @@ -6,6 +6,7 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.RenderContext; import com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers.OutgoingEventStreamRenderer; import org.junit.jupiter.api.Test; import software.amazon.smithy.build.MockManifest; @@ -97,8 +98,9 @@ private static String render(Model model, Protocol protocol) { CppWriterDelegator delegator = new CppWriterDelegator(manifest); List outgoing = List.of(model.expectShape(ShapeId.from("com.example#BidirectionalInput"))); - new OutgoingEventStreamRenderer(outgoing, model, service, ProtocolResolver.traitsFor(protocol), - "Example", "AWS_EXAMPLE_API", "example").render(delegator); + new OutgoingEventStreamRenderer(outgoing, + new RenderContext(model, service, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example")).render(delegator); delegator.flushWriters(); return manifest.getFileString(manifest.getFiles().stream() .filter(p -> p.toString().endsWith("BidirectionalInput.h")).findFirst().orElseThrow()).orElseThrow(); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ProtocolTraitsCharacterizationTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ProtocolTraitsCharacterizationTest.java index df51a773ed36..dfe9d2bf2f1a 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ProtocolTraitsCharacterizationTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ProtocolTraitsCharacterizationTest.java @@ -10,6 +10,7 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers.ResultRenderer; import com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers.SubObjectRenderer; import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.ProtocolTraits; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.RenderContext; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; @@ -122,12 +123,11 @@ private static java.util.Map renderAll(Protocol p) { CppWriterDelegator delegator = new CppWriterDelegator(manifest); ProtocolTraits traits = ProtocolResolver.traitsFor(resolved); - new SubObjectRenderer(classified.subObjects(), model, service, traits, - "Example", "AWS_EXAMPLE_API", "Example", "example").render(delegator); - new RequestRenderer(classified.requests(), model, service, traits, - "Example", "AWS_EXAMPLE_API", "example").render(delegator); - new ResultRenderer(classified.results(), model, service, traits, - "Example", "AWS_EXAMPLE_API", "example").render(delegator); + RenderContext ctx = new RenderContext(model, service, traits, + "Example", "AWS_EXAMPLE_API", "example"); + new SubObjectRenderer(classified.subObjects(), ctx).render(delegator); + new RequestRenderer(classified.requests(), ctx).render(delegator); + new ResultRenderer(classified.results(), ctx).render(delegator); delegator.flushWriters(); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RequestRendererTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RequestRendererTest.java index 94e9e0e107e8..0d204db610ed 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RequestRendererTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RequestRendererTest.java @@ -6,6 +6,7 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.RenderContext; import com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers.RequestRenderer; import org.junit.jupiter.api.Test; import software.amazon.smithy.build.MockManifest; @@ -76,8 +77,8 @@ private static String renderStreamingOp(boolean inputStreams, boolean outputStre Protocol protocol = ProtocolResolver.resolve(service, model); RequestRenderer renderer = new RequestRenderer( ShapeClassifier.classify(model, service, protocol).requests(), - model, service, ProtocolResolver.traitsFor(protocol), - "Example", "AWS_EXAMPLE_API", "example"); + new RenderContext(model, service, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example")); renderer.render(delegator); delegator.flushWriters(); return manifest.getFileString( @@ -213,8 +214,8 @@ void requestWithQueryMember_doesNotIncludeUriHeader() { Protocol protocol = ProtocolResolver.resolve(service, model); new RequestRenderer( ShapeClassifier.classify(model, service, protocol).requests(), - model, service, ProtocolResolver.traitsFor(protocol), - "Example", "AWS_EXAMPLE_API", "example").render(delegator); + new RenderContext(model, service, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example")).render(delegator); delegator.flushWriters(); String h = manifest.getFileString(manifest.getFiles().stream() .filter(p -> p.toString().endsWith("DoThingRequest.h")).findFirst().orElseThrow()).orElseThrow(); @@ -253,8 +254,8 @@ private static String renderRawStreamingPayloadRequest(String fileSuffix) { Protocol protocol = ProtocolResolver.resolve(service, model); new RequestRenderer( ShapeClassifier.classify(model, service, protocol).requests(), - model, service, ProtocolResolver.traitsFor(protocol), - "Example", "AWS_EXAMPLE_API", "example").render(delegator); + new RenderContext(model, service, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example")).render(delegator); delegator.flushWriters(); return manifest.getFileString(manifest.getFiles().stream() .filter(p -> p.toString().endsWith(fileSuffix)).findFirst().orElseThrow()).orElseThrow(); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ResultRendererTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ResultRendererTest.java index de80120fd8de..eeea14d4920b 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ResultRendererTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ResultRendererTest.java @@ -6,6 +6,7 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.RenderContext; import com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers.ResultRenderer; import org.junit.jupiter.api.Test; import software.amazon.smithy.build.MockManifest; @@ -49,8 +50,8 @@ private static String renderResultHeader(Trait protocolTrait) { Protocol protocol = ProtocolResolver.resolve(service, model); new ResultRenderer( ShapeClassifier.classify(model, service, protocol).results(), - model, service, ProtocolResolver.traitsFor(protocol), - "Example", "AWS_EXAMPLE_API", "example").render(delegator); + new RenderContext(model, service, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example")).render(delegator); delegator.flushWriters(); return manifest.getFileString(manifest.getFiles().stream() .filter(p -> p.toString().endsWith("DoThingResult.h")).findFirst().orElseThrow()).orElseThrow(); @@ -101,8 +102,8 @@ private static String renderStreaming(String fileSuffix) { Protocol protocol = ProtocolResolver.resolve(service, model); new ResultRenderer( ShapeClassifier.classify(model, service, protocol).results(), - model, service, ProtocolResolver.traitsFor(protocol), - "Example", "AWS_EXAMPLE_API", "example").render(delegator); + new RenderContext(model, service, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example")).render(delegator); delegator.flushWriters(); return manifest.getFileString(manifest.getFiles().stream() .filter(p -> p.toString().endsWith(fileSuffix)).findFirst().orElseThrow()).orElseThrow(); @@ -259,8 +260,8 @@ private static String renderResultSource(Model model, String fileSuffix) { Protocol protocol = ProtocolResolver.resolve(service, model); new ResultRenderer( ShapeClassifier.classify(model, service, protocol).results(), - model, service, ProtocolResolver.traitsFor(protocol), - "Example", "AWS_EXAMPLE_API", "example").render(delegator); + new RenderContext(model, service, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example")).render(delegator); delegator.flushWriters(); return manifest.getFileString(manifest.getFiles().stream() .filter(p -> p.toString().endsWith(fileSuffix)).findFirst().orElseThrow()).orElseThrow(); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ShapeClassifierTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ShapeClassifierTest.java index 9e028dbf7a49..7c709a1e0621 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ShapeClassifierTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ShapeClassifierTest.java @@ -4,7 +4,6 @@ */ package com.amazonaws.util.awsclientsmithygenerator.generators.model; -import com.amazonaws.util.awsclientsmithygenerator.generators.model.ShapeClassifier.Classification; import org.junit.jupiter.api.Test; import software.amazon.smithy.model.Model; import software.amazon.smithy.model.shapes.*; diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SubObjectRendererTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SubObjectRendererTest.java index 198304fd0bbb..e51cade9ea37 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SubObjectRendererTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SubObjectRendererTest.java @@ -7,6 +7,7 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.ProtocolTraits; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.RenderContext; import com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers.SubObjectRenderer; import org.junit.jupiter.api.Test; import software.amazon.smithy.build.MockManifest; @@ -90,8 +91,9 @@ private static java.util.Map renderAll() { model.expectShape(ShapeId.from("com.example#BidirectionalInput")), model.expectShape(ShapeId.from("com.example#AnyToolChoice")), model.expectShape(ShapeId.from("com.example#AudioSource"))); - new SubObjectRenderer(subObjects, model, service, traits, - "Example", "AWS_EXAMPLE_API", "Example", "example").render(delegator); + new SubObjectRenderer(subObjects, + new RenderContext(model, service, traits, + "Example", "AWS_EXAMPLE_API", "example")).render(delegator); delegator.flushWriters(); java.util.Map out = new java.util.TreeMap<>(); for (java.nio.file.Path path : manifest.getFiles()) { diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsSerdeTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsSerdeTest.java index 8a8964a9ad09..39a7858d7bdd 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsSerdeTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsSerdeTest.java @@ -73,8 +73,8 @@ void defaultPredicates_detectHeaderAndQueryMembers() { software.amazon.smithy.model.Model.builder().addShapes(str, req).build(); ProtocolTraits t = ProtocolResolver.traitsFor(ProtocolResolver.Protocol.JSON); - assertTrue(t.requestHasHeaderMembers(req, model)); - assertTrue(t.requestHasQueryStringMembers(req, model)); + assertTrue(RequestBindings.hasHeaderMembers(req, model)); + assertTrue(RequestBindings.hasQueryStringMembers(req, model)); } @Test @@ -90,8 +90,8 @@ void defaultPredicates_falseWhenNoBindings() { software.amazon.smithy.model.Model model = software.amazon.smithy.model.Model.builder().addShapes(str, req).build(); ProtocolTraits t = ProtocolResolver.traitsFor(ProtocolResolver.Protocol.REST_XML); - assertFalse(t.requestHasHeaderMembers(req, model)); - assertFalse(t.requestHasQueryStringMembers(req, model)); + assertFalse(RequestBindings.hasHeaderMembers(req, model)); + assertFalse(RequestBindings.hasQueryStringMembers(req, model)); } /** The JSON serde method bodies are empty stubs pending schema-based serde. */ diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsStreamingPayloadTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsStreamingPayloadTest.java index 589b6cdf29e3..76be69124d09 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsStreamingPayloadTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsStreamingPayloadTest.java @@ -88,7 +88,7 @@ private static String renderDecls(ProtocolTraits traits, Model model) { void allProtocols_omitSerializePayload_forRawStreamingPayloadRequest() { Model model = streamingPayloadModel(); for (ProtocolTraits traits : allTraits()) { - assertFalse(traits.emitsSerializePayload(op(model), model), + assertFalse(RequestBindings.emitsSerializePayload(op(model), model), traits.getClass().getSimpleName() + "/" + traits.protocol() + " must report emitsSerializePayload=false for a streaming-payload request"); assertFalse(renderDecls(traits, model).contains("SerializePayload"), @@ -101,7 +101,7 @@ void allProtocols_omitSerializePayload_forRawStreamingPayloadRequest() { void allProtocols_emitSerializePayload_forPlainRequest() { Model model = plainModel(); for (ProtocolTraits traits : allTraits()) { - assertTrue(traits.emitsSerializePayload(op(model), model), + assertTrue(RequestBindings.emitsSerializePayload(op(model), model), traits.getClass().getSimpleName() + "/" + traits.protocol() + " must report emitsSerializePayload=true for a plain request"); assertTrue(renderDecls(traits, model).contains("SerializePayload"), diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RequestBindingsTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RequestBindingsTest.java new file mode 100644 index 000000000000..53b2437b397c --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RequestBindingsTest.java @@ -0,0 +1,45 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol; + +import org.junit.jupiter.api.Test; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.MemberShape; +import software.amazon.smithy.model.shapes.StringShape; +import software.amazon.smithy.model.shapes.StructureShape; +import software.amazon.smithy.model.traits.HttpHeaderTrait; +import software.amazon.smithy.model.traits.HttpQueryTrait; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class RequestBindingsTest { + @Test + void detectsHeaderAndQueryMembers() { + StringShape str = StringShape.builder().id("com.example#S").build(); + StructureShape req = StructureShape.builder() + .id("com.example#Req") + .addMember(MemberShape.builder().id("com.example#Req$h").target(str.getId()) + .addTrait(new HttpHeaderTrait("X-H")).build()) + .addMember(MemberShape.builder().id("com.example#Req$q").target(str.getId()) + .addTrait(new HttpQueryTrait("q")).build()) + .build(); + Model model = Model.builder().addShapes(str, req).build(); + assertTrue(RequestBindings.hasHeaderMembers(req, model)); + assertTrue(RequestBindings.hasQueryStringMembers(req, model)); + } + + @Test + void plainStructHasNeither() { + StringShape str = StringShape.builder().id("com.example#S2").build(); + StructureShape req = StructureShape.builder() + .id("com.example#Plain") + .addMember(MemberShape.builder().id("com.example#Plain$a").target(str.getId()).build()) + .build(); + Model model = Model.builder().addShapes(str, req).build(); + assertFalse(RequestBindings.hasHeaderMembers(req, model)); + assertFalse(RequestBindings.hasQueryStringMembers(req, model)); + } +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSetsTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSetsTest.java index 043bd71d4b12..b80a15c8bc30 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSetsTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSetsTest.java @@ -70,6 +70,19 @@ void emit_dedupsAndSortsAndWrapsInAngleBrackets() { assertTrue(out.indexOf("a/a.h") < out.indexOf("b/z.h"), out); } + @Test + void emitAngleIncludes_normalizesBracketsDedupesAndSorts() { + com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter writer = + new com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter(); + IncludeSets.emitAngleIncludes(writer, java.util.List.of( + "", "aws/a/A.h", "")); + String out = writer.toString(); + // deduped to two, each bracketed exactly once, sorted A before B + assertEquals( + "#include \n#include \n", + out); + } + @Test void emitUsings_preservesOrder() { com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter w = diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ModelFileTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ModelFileTest.java new file mode 100644 index 000000000000..f24873ec9756 --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ModelFileTest.java @@ -0,0 +1,29 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers; + +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class ModelFileTest { + @Test + void modelNamespace_matchesHandWrittenTripleNest() { + CppWriter manual = new CppWriter(); + manual.writeNamespaceOpen("Aws"); + manual.writeNamespaceOpen("S3"); + manual.writeNamespaceOpen("Model"); + manual.write("int x = 1;"); + manual.writeNamespaceClose("Model"); + manual.writeNamespaceClose("S3"); + manual.writeNamespaceClose("Aws"); + + CppWriter viaHelper = new CppWriter(); + ModelFile.modelNamespace(viaHelper, "S3", () -> viaHelper.write("int x = 1;")); + + assertEquals(manual.toString(), viaHelper.toString()); + } +} From bc6df49d5f1cd3a92e1c7f0e507fbc28864d4efb Mon Sep 17 00:00:00 2001 From: sbaluja Date: Wed, 12 Aug 2026 14:33:14 -0400 Subject: [PATCH 03/19] Allow extra includes - refactor and cleanup Route interleaved header namespaces through ModelFile prolog overload Fold member-driven source includes into protocol union; drop per-member scan (#0000) Collapse serde source-include switches into per-protocol union (#0000) Loosen model-plugin include assertions to superset; keep usings exact (#0000) --- .../generators/model/CppTypeMapper.java | 44 ------------------- .../model/protocol/CborProtocolTraits.java | 43 +++++------------- .../model/protocol/JsonProtocolTraits.java | 35 +++++---------- .../protocol/QueryXmlProtocolTraits.java | 24 +++------- .../model/protocol/RestXmlProtocolTraits.java | 33 +++++--------- .../model/renderers/EventStreamRenderer.java | 31 +++++-------- .../model/renderers/IncludeSets.java | 18 ++++++++ .../generators/model/renderers/ModelFile.java | 13 ++++++ .../model/renderers/RequestRenderer.java | 17 +++---- .../model/renderers/ResultRenderer.java | 42 +++++++----------- .../model/renderers/SubObjectRenderer.java | 20 +++------ .../generators/model/CppTypeMapperTest.java | 41 ----------------- .../ProtocolTraitsCharacterizationTest.java | 36 +-------------- .../model/SubObjectRendererTest.java | 7 --- .../protocol/CborProtocolTraitsTest.java | 7 ++- .../ProtocolTraitsIncludeSetTest.java | 21 +++------ .../model/renderers/IncludeSetsTest.java | 27 ++++++++++++ .../model/renderers/ModelFileTest.java | 20 +++++++++ 18 files changed, 174 insertions(+), 305 deletions(-) diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java index 92e5835eb31a..82a86872e8cb 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java @@ -10,10 +10,6 @@ import software.amazon.smithy.model.shapes.MemberShape; import software.amazon.smithy.model.shapes.Shape; import software.amazon.smithy.model.shapes.StructureShape; -import software.amazon.smithy.model.traits.HttpHeaderTrait; -import software.amazon.smithy.model.traits.HttpPrefixHeadersTrait; -import software.amazon.smithy.model.traits.HttpQueryParamsTrait; -import software.amazon.smithy.model.traits.HttpQueryTrait; import software.amazon.smithy.model.traits.IdempotencyTokenTrait; import software.amazon.smithy.model.traits.SensitiveTrait; @@ -258,44 +254,4 @@ public static List getIncludesForShape(Shape structureShape, Model model return new ArrayList<>(includes); } - /** - * Returns the serde-implementation includes a shape's source file needs, as bare - * paths (no angle brackets). Mirrors C2J's {@code CppViewHelper.computeSourceIncludes}: - * a blob member (or list/map of blobs) pulls {@code HashingUtils.h} for Base64 serde, and a - * header/query-bound member pulls {@code AWSStringStream.h}. These are distinct from the - * member-type includes returned by {@link #getIncludesForShape} (which serve the - * header); C2J keeps the two sets separate and lists in the source only what the header does - * not already provide. - */ - public static List getSourceIncludesForShape(Shape structureShape, Model model, String projectName) { - Set includes = new TreeSet<>(); - for (MemberShape member : structureShape.getAllMembers().values()) { - Shape target = model.expectShape(member.getTarget()); - if (referencesBlob(target, model)) { - includes.add("aws/core/utils/HashingUtils.h"); - } else if (member.hasTrait(HttpHeaderTrait.class) - || member.hasTrait(HttpPrefixHeadersTrait.class) - || member.hasTrait(HttpQueryTrait.class) - || member.hasTrait(HttpQueryParamsTrait.class)) { - includes.add("aws/core/utils/memory/stl/AWSStringStream.h"); - } - } - return new ArrayList<>(includes); - } - - /** True if {@code shape} is a blob, a list of blobs, or a map whose key or value is a blob. */ - private static boolean referencesBlob(Shape shape, Model model) { - if (shape.isBlobShape()) { - return true; - } - if (shape.isListShape()) { - return model.expectShape(shape.asListShape().get().getMember().getTarget()).isBlobShape(); - } - if (shape.isMapShape()) { - MapShape map = shape.asMapShape().get(); - return model.expectShape(map.getKey().getTarget()).isBlobShape() - || model.expectShape(map.getValue().getTarget()).isBlobShape(); - } - return false; - } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraits.java index e498c03bfc2f..c4aa6857087d 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraits.java @@ -78,38 +78,19 @@ public void writeResultSerdeDecls(CppWriter writer, String exportMacro, String c @Override public java.util.List serdeIncludes(FileKind kind) { - switch (kind) { - case RESULT_SOURCE: - return java.util.List.of( - "aws/crt/cbor/Cbor.h", - "aws/core/utils/cbor/CborValue.h", - "aws/core/utils/UnreferencedParam.h", - "aws/core/utils/memory/stl/AWSStringStream.h"); - case INITIAL_RESPONSE_SOURCE: - return java.util.List.of( - "aws/crt/cbor/Cbor.h", - "aws/core/utils/cbor/CborValue.h", - "aws/core/utils/UnreferencedParam.h"); - case REQUEST_SOURCE: - // CborRequestSource.vm: request payloads encode via the streaming CborEncoder, - // so NO DOM header here. - return java.util.List.of("aws/crt/cbor/Cbor.h", "utility"); - case STREAMING_RESULT_SOURCE: - return java.util.List.of(); - case SUBOBJECT_HEADER: - // CborSubObjectHeader.vm hard-includes : the ctor/operator= - // reference Aws::Crt::Cbor::CborDecoder and CborEncode takes a CborEncoder&. - return java.util.List.of("aws/crt/cbor/Cbor.h"); - case RESULT_HEADER: - // CborResultHeader.vm hard-includes as well. - return java.util.List.of("aws/crt/cbor/Cbor.h"); - case SUBOBJECT_SOURCE: - case EVENT_HANDLER_SOURCE: - return java.util.List.of("aws/crt/cbor/Cbor.h", "aws/core/utils/cbor/CborValue.h"); - default: - throw new UnsupportedOperationException( - "No serde includes defined for FileKind " + kind + " in CborProtocolTraits"); + // CborSubObjectHeader.vm / CborResultHeader.vm hard-include : the + // header signatures reference Aws::Crt::Cbor::CborDecoder / CborEncoder directly. + if (kind == FileKind.SUBOBJECT_HEADER || kind == FileKind.RESULT_HEADER) { + return java.util.List.of("aws/crt/cbor/Cbor.h"); } + // All source kinds share one union (supersets allowed). Usings are unchanged. + return java.util.List.of( + "aws/crt/cbor/Cbor.h", + "aws/core/utils/cbor/CborValue.h", + "aws/core/utils/UnreferencedParam.h", + "aws/core/utils/memory/stl/AWSStringStream.h", + "aws/core/utils/HashingUtils.h", + "utility"); } @Override diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraits.java index a40cc03c290d..2e73779b3b99 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraits.java @@ -81,31 +81,18 @@ public void writeResultSerdeDecls(CppWriter writer, String exportMacro, String c @Override public java.util.List serdeIncludes(FileKind kind) { - switch (kind) { - case RESULT_SOURCE: - return java.util.List.of( - "aws/core/utils/json/JsonSerializer.h", - "aws/core/utils/UnreferencedParam.h", - "aws/core/utils/memory/stl/AWSStringStream.h"); - case INITIAL_RESPONSE_SOURCE: - return java.util.List.of( - "aws/core/utils/json/JsonSerializer.h", - "aws/core/utils/UnreferencedParam.h"); - case REQUEST_SOURCE: - return java.util.List.of("aws/core/utils/json/JsonSerializer.h", "utility"); - case STREAMING_RESULT_SOURCE: - return java.util.List.of(); - case SUBOBJECT_HEADER: - case RESULT_HEADER: - // Sub-object and result headers forward-declare JsonValue/JsonView; no serializer include. - return java.util.List.of(); - case SUBOBJECT_SOURCE: - case EVENT_HANDLER_SOURCE: - return java.util.List.of("aws/core/utils/json/JsonSerializer.h"); - default: - throw new UnsupportedOperationException( - "No serde includes defined for FileKind " + kind + " in JsonProtocolTraits"); + // Headers forward-declare JsonValue/JsonView; no serializer include. + if (kind == FileKind.SUBOBJECT_HEADER || kind == FileKind.RESULT_HEADER) { + return java.util.List.of(); } + // All source kinds share one union (supersets allowed: a .cpp may carry an + // include it doesn't strictly use). Usings are unchanged; only #includes widen. + return java.util.List.of( + "aws/core/utils/json/JsonSerializer.h", + "aws/core/utils/UnreferencedParam.h", + "aws/core/utils/memory/stl/AWSStringStream.h", + "aws/core/utils/HashingUtils.h", + "utility"); } @Override diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/QueryXmlProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/QueryXmlProtocolTraits.java index ee13e9156e9d..62b45bc4ab97 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/QueryXmlProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/QueryXmlProtocolTraits.java @@ -93,26 +93,16 @@ public java.util.List serdeIncludes(FileKind kind) { case RESULT_HEADER: // Query/EC2 result headers forward-declare XmlDocument; no serde include. return java.util.List.of(); - case RESULT_SOURCE: - return java.util.List.of( - "aws/core/utils/xml/XmlSerializer.h", - "aws/core/utils/logging/LogMacros.h"); - case INITIAL_RESPONSE_SOURCE: + default: + // All source kinds share one union (supersets allowed). Usings are unchanged. + // No Query source arm carried , so the union omits it. return java.util.List.of( "aws/core/utils/xml/XmlSerializer.h", - "aws/core/utils/UnreferencedParam.h"); - case REQUEST_SOURCE: - return java.util.List.of( + "aws/core/utils/logging/LogMacros.h", + "aws/core/utils/UnreferencedParam.h", "aws/core/utils/StringUtils.h", - "aws/core/utils/memory/stl/AWSStringStream.h"); - case STREAMING_RESULT_SOURCE: - return java.util.List.of(); - case SUBOBJECT_SOURCE: - case EVENT_HANDLER_SOURCE: - return java.util.List.of("aws/core/utils/xml/XmlSerializer.h"); - default: - throw new UnsupportedOperationException( - "No serde includes defined for FileKind " + kind + " in QueryXmlProtocolTraits"); + "aws/core/utils/memory/stl/AWSStringStream.h", + "aws/core/utils/HashingUtils.h"); } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RestXmlProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RestXmlProtocolTraits.java index d59d4eff0bd6..e5bcfb44cadc 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RestXmlProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RestXmlProtocolTraits.java @@ -67,30 +67,17 @@ public void writeResultSerdeDecls(CppWriter writer, String exportMacro, String c @Override public java.util.List serdeIncludes(FileKind kind) { - switch (kind) { - case RESULT_SOURCE: - return java.util.List.of( - "aws/core/utils/xml/XmlSerializer.h", - "aws/core/utils/memory/stl/AWSStringStream.h"); - case INITIAL_RESPONSE_SOURCE: - return java.util.List.of( - "aws/core/utils/xml/XmlSerializer.h", - "aws/core/utils/UnreferencedParam.h"); - case REQUEST_SOURCE: - return java.util.List.of("aws/core/utils/xml/XmlSerializer.h", "utility"); - case STREAMING_RESULT_SOURCE: - return java.util.List.of(); - case SUBOBJECT_HEADER: - case RESULT_HEADER: - // Sub-object and result headers forward-declare XmlNode/XmlDocument; no serializer include. - return java.util.List.of(); - case SUBOBJECT_SOURCE: - case EVENT_HANDLER_SOURCE: - return java.util.List.of("aws/core/utils/xml/XmlSerializer.h"); - default: - throw new UnsupportedOperationException( - "No serde includes defined for FileKind " + kind + " in RestXmlProtocolTraits"); + // Sub-object and result headers forward-declare XmlNode/XmlDocument; no serializer include. + if (kind == FileKind.SUBOBJECT_HEADER || kind == FileKind.RESULT_HEADER) { + return java.util.List.of(); } + // All source kinds share one union (supersets allowed). Usings are unchanged. + return java.util.List.of( + "aws/core/utils/xml/XmlSerializer.h", + "aws/core/utils/memory/stl/AWSStringStream.h", + "aws/core/utils/UnreferencedParam.h", + "aws/core/utils/HashingUtils.h", + "utility"); } @Override diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EventStreamRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EventStreamRenderer.java index d20342148de8..fcc5283a4c67 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EventStreamRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EventStreamRenderer.java @@ -230,8 +230,8 @@ private void renderHandlerSource(CppWriterDelegator writerDelegator, String opNa includes.add("aws/core/utils/logging/LogMacros.h"); includes.add("aws/" + ctx.smithyServiceName() + "/" + ctx.namespace() + "ErrorMarshaller.h"); includes.add("aws/" + ctx.smithyServiceName() + "/model/" + opName + "Handler.h"); - includes.addAll(ctx.protocolTraits().serdeIncludes(FileKind.EVENT_HANDLER_SOURCE)); - IncludeSets.emit(writer, includes); + IncludeSets.emitSourceIncludes(writer, includes, + ctx.protocolTraits(), FileKind.EVENT_HANDLER_SOURCE); writer.write(""); writer.write("using namespace Aws::$1L::Model;", ctx.namespace()); writer.write("using namespace Aws::Utils::Event;"); @@ -448,10 +448,9 @@ private void renderInitialResponse(CppWriterDelegator writerDelegator, String op writer.write("#include "); } writer.write(""); - writer.withNamespace("Aws", () -> { - ctx.protocolTraits().writeShapeForwardDeclarations(writer); - writer.withNamespace(ctx.namespace(), () -> - writer.withNamespace("Model", () -> { + ModelFile.modelNamespace(writer, ctx.namespace(), + () -> ctx.protocolTraits().writeShapeForwardDeclarations(writer), + () -> { writer.write(""); writer.openBlock("class $L {", "};", className, () -> { writer.write("public:"); @@ -471,8 +470,7 @@ private void renderInitialResponse(CppWriterDelegator writerDelegator, String op } }); writer.write(""); - })); - }); + }); }); String sourceFile = "source/model/" + className + ".cpp"; @@ -481,11 +479,8 @@ private void renderInitialResponse(CppWriterDelegator writerDelegator, String op includes.add("aws/core/utils/StringUtils.h"); includes.add("aws/" + ctx.smithyServiceName() + "/model/" + className + ".h"); includes.add("utility"); - includes.addAll(ctx.protocolTraits().serdeIncludes(FileKind.INITIAL_RESPONSE_SOURCE)); - // Serde-implementation includes derived from the initial-response members (e.g. - // AWSStringStream.h for the header-bound members), matching C2J computeSourceIncludes. - includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, ctx.model(), ctx.smithyServiceName())); - IncludeSets.emit(writer, includes); + IncludeSets.emitSourceIncludes(writer, includes, + ctx.protocolTraits(), FileKind.INITIAL_RESPONSE_SOURCE); writer.write(""); IncludeSets.emitUsings(writer, ctx.protocolTraits().serdeUsings(FileKind.INITIAL_RESPONSE_SOURCE)); writer.write(""); @@ -529,10 +524,9 @@ private void renderEventStreamUnion(CppWriterDelegator writerDelegator, String o writer.write(""); writer.write("#include "); writer.write(""); - writer.withNamespace("Aws", () -> { - ctx.protocolTraits().writeShapeForwardDeclarations(writer); - writer.withNamespace(ctx.namespace(), () -> - writer.withNamespace("Model", () -> { + ModelFile.modelNamespace(writer, ctx.namespace(), + () -> ctx.protocolTraits().writeShapeForwardDeclarations(writer), + () -> { writer.write(""); MemberRenderer.renderClassDocComment(writer, union, ctx.smithyServiceName(), ctx.service().getVersion()); writer.openBlock("class $L {", "};", className, () -> { @@ -568,8 +562,7 @@ private void renderEventStreamUnion(CppWriterDelegator writerDelegator, String o } }); writer.write(""); - })); - }); + }); }); // C2J generates the event stream union as a header-only type: the serde methods are diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSets.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSets.java index 6b25f4427fc1..4b9e8f410327 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSets.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSets.java @@ -4,6 +4,10 @@ */ package com.amazonaws.util.awsclientsmithygenerator.generators.model.renderers; +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.FileKind; +import com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.ProtocolTraits; + import java.util.ArrayList; import java.util.List; @@ -74,6 +78,20 @@ static List subObjectSourceBase(String smithyServiceName, String classNa return inc; } + /** + * Assembles and emits a source file's {@code #include} block: the per-site {@code base} + * (self-header, {@code AmazonWebServiceResult.h}, etc.) plus the protocol's source-include + * union for {@code kind}. The two lists are concatenated then emitted via {@link #emit}, + * which dedups, sorts (CaseSensitive) and brackets. Usings are emitted separately by the + * caller via {@link #emitUsings} — this method never touches usings. + */ + static void emitSourceIncludes(CppWriter writer, List base, + ProtocolTraits traits, FileKind kind) { + List includes = new ArrayList<>(base); + includes.addAll(traits.serdeIncludes(kind)); + emit(writer, includes); + } + /** Writes each path as {@code #include }, deduped and sorted (CaseSensitive). */ static void emit(com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter writer, List includePaths) { diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ModelFile.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ModelFile.java index 3c5a94650729..8e21fe78903d 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ModelFile.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ModelFile.java @@ -21,4 +21,17 @@ static void modelNamespace(CppWriter writer, String namespace, Runnable body) { writer.withNamespace(namespace, () -> writer.withNamespace("Model", body))); } + + /** + * Like {@link #modelNamespace(CppWriter, String, Runnable)} but emits {@code awsProlog} + * directly inside {@code Aws} — before opening {@code namespace} — for headers that must + * place forward declarations (e.g. {@code AmazonWebServiceResult}, serde value types) at + * {@code Aws} scope. The body still renders inside {@code Aws::::Model}. + */ + static void modelNamespace(CppWriter writer, String namespace, Runnable awsProlog, Runnable body) { + writer.withNamespace("Aws", () -> { + awsProlog.run(); + writer.withNamespace(namespace, () -> writer.withNamespace("Model", body)); + }); + } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java index 1ca457c227ab..a45808469c58 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java @@ -244,7 +244,12 @@ private void renderSource(CppWriterDelegator writerDelegator, IncludeSets.requestSourceBase(ctx.smithyServiceName(), className)); includes.add("aws/core/AmazonWebServiceResult.h"); includes.add("utility"); - includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, ctx.model(), ctx.smithyServiceName())); + // A raw-streaming-payload request sends its body via the streaming base class (no + // protocol serde), but its header/query members still serialize, so the source + // needs HashingUtils.h (blob Base64) and AWSStringStream.h unconditionally. It must + // NOT pull the protocol serde header (e.g. JsonSerializer.h), matching C2J. + includes.add("aws/core/utils/HashingUtils.h"); + includes.add("aws/core/utils/memory/stl/AWSStringStream.h"); IncludeSets.emit(writer, includes); writer.write(""); writer.write("using namespace Aws::$L::Model;", ctx.namespace()); @@ -267,13 +272,9 @@ private void renderSource(CppWriterDelegator writerDelegator, return; } - List includes = new ArrayList<>( - IncludeSets.requestSourceBase(ctx.smithyServiceName(), className)); - includes.addAll(ctx.protocolTraits().serdeIncludes(FileKind.REQUEST_SOURCE)); - // Serde-implementation includes derived from members (HashingUtils.h for blob Base64 - // serde, AWSStringStream.h for header/query members), matching C2J computeSourceIncludes. - includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, ctx.model(), ctx.smithyServiceName())); - IncludeSets.emit(writer, includes); + IncludeSets.emitSourceIncludes(writer, + IncludeSets.requestSourceBase(ctx.smithyServiceName(), className), + ctx.protocolTraits(), FileKind.REQUEST_SOURCE); writer.write(""); writer.write("using namespace Aws::$L::Model;", ctx.namespace()); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ResultRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ResultRenderer.java index 39b981fbaa1c..9509f62a066b 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ResultRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ResultRenderer.java @@ -85,14 +85,14 @@ private void renderHeader(CppWriterDelegator writerDelegator, writer.write("#include "); writer.write(""); - writer.withNamespace("Aws", () -> { + ModelFile.modelNamespace(writer, ctx.namespace(), + () -> { writer.write("template "); writer.write("class AmazonWebServiceResult;"); writer.write(""); ctx.protocolTraits().writeResultForwardDeclarations(writer); - - writer.withNamespace(ctx.namespace(), () -> - writer.withNamespace("Model", () -> { + }, + () -> { if (shape.getTrait(DocumentationTrait.class).isPresent()) { MemberRenderer.renderClassDocComment(writer, shape, ctx.smithyServiceName(), ctx.service().getVersion()); @@ -132,8 +132,7 @@ private void renderHeader(CppWriterDelegator writerDelegator, } }); writer.write(""); - })); - }); + }); }); } @@ -143,13 +142,9 @@ private void renderSource(CppWriterDelegator writerDelegator, String fileName = "source/model/" + className + ".cpp"; writerDelegator.useFileWriter(fileName, writer -> { - List includes = new java.util.ArrayList<>( - IncludeSets.resultSourceBase(ctx.smithyServiceName(), className)); - includes.addAll(ctx.protocolTraits().serdeIncludes(FileKind.RESULT_SOURCE)); - // Serde-implementation includes derived from members (HashingUtils.h for blob Base64 - // serde, AWSStringStream.h for header/query members), matching C2J computeSourceIncludes. - includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, ctx.model(), ctx.smithyServiceName())); - IncludeSets.emit(writer, includes); + IncludeSets.emitSourceIncludes(writer, + IncludeSets.resultSourceBase(ctx.smithyServiceName(), className), + ctx.protocolTraits(), FileKind.RESULT_SOURCE); writer.write(""); writer.write("using namespace Aws::$L::Model;", ctx.namespace()); IncludeSets.emitUsings(writer, ctx.protocolTraits().serdeUsings(FileKind.RESULT_SOURCE)); @@ -185,13 +180,13 @@ private void renderStreamingHeader(CppWriterDelegator writerDelegator, writer.write("#include "); writer.write(""); - writer.withNamespace("Aws", () -> { + ModelFile.modelNamespace(writer, ctx.namespace(), + () -> { writer.write("template "); writer.write("class AmazonWebServiceResult;"); writer.write(""); - - writer.withNamespace(ctx.namespace(), () -> - writer.withNamespace("Model", () -> { + }, + () -> { if (shape.getTrait(DocumentationTrait.class).isPresent()) { MemberRenderer.renderClassDocComment(writer, shape, ctx.smithyServiceName(), ctx.service().getVersion()); @@ -250,8 +245,7 @@ private void renderStreamingHeader(CppWriterDelegator writerDelegator, writer.write("bool m_requestIdHasBeenSet = false;"); }); writer.write(""); - })); - }); + }); }); } @@ -265,13 +259,9 @@ private void renderStreamingSource(CppWriterDelegator writerDelegator, String streamField = CppNames.fieldName(streamingPayloadMemberName(shape)); String fileName = "source/model/" + className + ".cpp"; writerDelegator.useFileWriter(fileName, writer -> { - List includes = new java.util.ArrayList<>( - IncludeSets.streamingResultSourceBase(ctx.smithyServiceName(), className)); - includes.addAll(ctx.protocolTraits().serdeIncludes(FileKind.STREAMING_RESULT_SOURCE)); - // Serde-implementation includes derived from members (e.g. HashingUtils.h for the - // blob payload member's Base64 serde), matching C2J computeSourceIncludes. - includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, ctx.model(), ctx.smithyServiceName())); - IncludeSets.emit(writer, includes); + IncludeSets.emitSourceIncludes(writer, + IncludeSets.streamingResultSourceBase(ctx.smithyServiceName(), className), + ctx.protocolTraits(), FileKind.STREAMING_RESULT_SOURCE); writer.write(""); writer.write("using namespace Aws::$L::Model;", ctx.namespace()); writer.write("using namespace Aws::Utils::Stream;"); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/SubObjectRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/SubObjectRenderer.java index 76d2ddcf95b5..8b4f296bf3ea 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/SubObjectRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/SubObjectRenderer.java @@ -69,10 +69,9 @@ private void renderHeader(CppWriterDelegator writerDelegator, Shape shape) { } writer.write(""); - writer.withNamespace("Aws", () -> { - ctx.protocolTraits().writeShapeForwardDeclarations(writer); - writer.withNamespace(ctx.namespace(), () -> - writer.withNamespace("Model", () -> { + ModelFile.modelNamespace(writer, ctx.namespace(), + () -> ctx.protocolTraits().writeShapeForwardDeclarations(writer), + () -> { writer.write(""); MemberRenderer.renderClassDocComment(writer, shape, ctx.smithyServiceName(), ctx.service().getVersion()); @@ -94,8 +93,7 @@ private void renderHeader(CppWriterDelegator writerDelegator, Shape shape) { } }); writer.write(""); - })); - }); + }); }); } @@ -104,13 +102,9 @@ private void renderSource(CppWriterDelegator writerDelegator, Shape shape) { String fileName = "source/model/" + className + ".cpp"; writerDelegator.useFileWriter(fileName, writer -> { - List includes = new java.util.ArrayList<>( - IncludeSets.subObjectSourceBase(ctx.smithyServiceName(), className)); - includes.addAll(ctx.protocolTraits().serdeIncludes(FileKind.SUBOBJECT_SOURCE)); - // Serde-implementation includes derived from members (e.g. HashingUtils.h for blob - // Base64 serde), matching C2J's computeSourceIncludes. - includes.addAll(CppTypeMapper.getSourceIncludesForShape(shape, ctx.model(), ctx.smithyServiceName())); - IncludeSets.emit(writer, includes); + IncludeSets.emitSourceIncludes(writer, + IncludeSets.subObjectSourceBase(ctx.smithyServiceName(), className), + ctx.protocolTraits(), FileKind.SUBOBJECT_SOURCE); writer.write(""); IncludeSets.emitUsings(writer, ctx.protocolTraits().serdeUsings(FileKind.SUBOBJECT_SOURCE)); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapperTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapperTest.java index 5784227730d6..cf41e3277fd7 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapperTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapperTest.java @@ -426,45 +426,4 @@ void getIncludesForShape_withMapMember_includesMapKeyAndValue() { assertTrue(includes.contains("")); assertTrue(includes.contains("")); } - - // --- getSourceIncludesForShape tests (serde-implementation includes) --- - - @Test - void getSourceIncludesForShape_withBlobMember_includesHashingUtils() { - // C2J adds HashingUtils.h to the SOURCE of any shape with a blob member (or list/map of - // blobs) because blob serde uses Base64Encode/Decode (CppViewHelper.computeSourceIncludes). - BlobShape blob = BlobShape.builder().id("com.example#Body").build(); - StructureShape struct = StructureShape.builder() - .id("com.example#AudioSource").addMember("bytes", blob.getId()).build(); - Model model = Model.builder().addShapes(blob, struct).build(); - - List inc = CppTypeMapper.getSourceIncludesForShape(struct, model, "myservice"); - assertTrue(inc.contains("aws/core/utils/HashingUtils.h"), inc.toString()); - } - - @Test - void getSourceIncludesForShape_withListOfBlobs_includesHashingUtils() { - BlobShape blob = BlobShape.builder().id("com.example#Body").build(); - ListShape list = ListShape.builder() - .id("com.example#BodyList") - .member(MemberShape.builder().id("com.example#BodyList$member").target("com.example#Body").build()) - .build(); - StructureShape struct = StructureShape.builder() - .id("com.example#MyShape").addMember("chunks", list.getId()).build(); - Model model = Model.builder().addShapes(blob, list, struct).build(); - - List inc = CppTypeMapper.getSourceIncludesForShape(struct, model, "myservice"); - assertTrue(inc.contains("aws/core/utils/HashingUtils.h"), inc.toString()); - } - - @Test - void getSourceIncludesForShape_withoutBlob_noHashingUtils() { - StringShape str = StringShape.builder().id("com.example#Str").build(); - StructureShape struct = StructureShape.builder() - .id("com.example#MyShape").addMember("name", str.getId()).build(); - Model model = Model.builder().addShapes(str, struct).build(); - - List inc = CppTypeMapper.getSourceIncludesForShape(struct, model, "myservice"); - assertFalse(inc.contains("aws/core/utils/HashingUtils.h"), inc.toString()); - } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ProtocolTraitsCharacterizationTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ProtocolTraitsCharacterizationTest.java index dfe9d2bf2f1a..01834ac14ae4 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ProtocolTraitsCharacterizationTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/ProtocolTraitsCharacterizationTest.java @@ -242,7 +242,6 @@ void jsonLike_subObjectSource_hasJsonIncludeUsingAndStubs(Protocol p) { assertTrue(c.contains("Nested& Nested::operator=(JsonView jsonValue) {"), c); assertTrue(c.contains("JsonValue Nested::Jsonize() const {"), c); assertTrue(c.contains("JsonValue payload;"), c); - assertFalse(c.contains("XmlSerializer.h"), c); } @Test @@ -253,7 +252,6 @@ void restXml_subObjectSource_hasXmlIncludeUsingAndStubs() { assertTrue(c.contains("Nested::Nested(const XmlNode& xmlNode) { *this = xmlNode; }"), c); assertTrue(c.contains("Nested& Nested::operator=(const XmlNode& xmlNode) {"), c); assertTrue(c.contains("void Nested::AddToNode(XmlNode& parentNode) const {"), c); - assertFalse(c.contains("JsonSerializer.h"), c); } @ParameterizedTest @@ -304,14 +302,6 @@ void jsonAndCbor_resultSource_includesUnreferencedParam(Protocol p) { assertTrue(c.contains("#include "), c); } - @ParameterizedTest - @EnumSource(value = Protocol.class, names = {"REST_XML", "QUERY_XML", "EC2"}) - void xmlLike_resultSource_omitsUnreferencedParam(Protocol p) { - // C2J XML-family result templates (rest-xml, query, ec2) do not include UnreferencedParam.h. - String c = file(p, "DoThingResult.cpp"); - assertFalse(c.contains("UnreferencedParam.h"), c); - } - @ParameterizedTest @EnumSource(value = Protocol.class, names = {"JSON", "REST_JSON", "REST_XML", "CBOR"}) void nonQuery_resultSource_includesAWSStringStream(Protocol p) { @@ -320,14 +310,6 @@ void nonQuery_resultSource_includesAWSStringStream(Protocol p) { assertTrue(c.contains("#include "), c); } - @ParameterizedTest - @EnumSource(value = Protocol.class, names = {"QUERY_XML", "EC2"}) - void queryLike_resultSource_omitsAWSStringStream(Protocol p) { - // Query/EC2 result sources build no string stream, so they omit AWSStringStream.h. - String c = file(p, "DoThingResult.cpp"); - assertFalse(c.contains("AWSStringStream.h"), c); - } - @ParameterizedTest @EnumSource(value = Protocol.class, names = {"JSON", "REST_JSON"}) void jsonLike_resultSource_hasJsonUsingsAndCtorImpls(Protocol p) { @@ -365,7 +347,6 @@ void jsonLike_requestSource_hasJsonIncludeAndUsings(Protocol p) { assertTrue(c.contains("using namespace Aws::Example::Model;"), c); assertTrue(c.contains("using namespace Aws::Utils::Json;"), c); assertTrue(c.contains("using namespace Aws::Utils;"), c); - assertFalse(c.contains("XmlSerializer.h"), c); } @Test @@ -373,23 +354,19 @@ void restXml_requestSource_hasXmlIncludeAndUsings() { String c = file(Protocol.REST_XML, "DoThingRequest.cpp"); assertTrue(c.contains("#include "), c); assertTrue(c.contains("using namespace Aws::Utils::Xml;"), c); - assertFalse(c.contains("JsonSerializer.h"), c); } @ParameterizedTest @EnumSource(value = Protocol.class, names = {"QUERY_XML", "EC2"}) void queryLike_requestSource_usesStringStreamNotXmlSerializer(Protocol p) { // Query/EC2 request bodies serialize to a query string (Action=...&Version=...), so the - // source uses StringUtils + AWSStringStream and NOT the XML serializer, matching C2J - // (QueryRequestSource.vm). The XML serde headers belong to the result/sub-object files. + // source uses StringUtils + AWSStringStream, matching C2J (QueryRequestSource.vm). String c = file(p, "DoThingRequest.cpp"); assertTrue(c.contains("#include "), c); assertTrue(c.contains("#include "), c); - assertFalse(c.contains("XmlSerializer.h"), c); + // Usings are held exact: Query/EC2 request sources must not open the XML namespace. assertFalse(c.contains("using namespace Aws::Utils::Xml;"), c); assertFalse(c.contains("JsonSerializer.h"), c); - // Query/EC2 request sources do not include (C2J QueryRequestSource.vm omits it). - assertFalse(c.contains("#include "), c); } @ParameterizedTest @@ -545,13 +522,4 @@ void queryLikeResultSource_includesLogMacrosForResponseMetadataDebug(Protocol p) assertTrue(c.contains("#include "), c); assertTrue(c.contains("using namespace Aws::Utils::Logging;"), c); } - - @ParameterizedTest - @EnumSource(value = Protocol.class, names = {"JSON", "REST_JSON", "REST_XML", "CBOR"}) - void nonQueryResultSource_omitsLogMacros(Protocol p) { - // Only Query/EC2 results reference the logging macros; other protocols must not - // pull in LogMacros.h. - String c = file(p, "DoThingResult.cpp"); - assertFalse(c.contains("LogMacros.h"), c); - } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SubObjectRendererTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SubObjectRendererTest.java index e51cade9ea37..9052f7abd91f 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SubObjectRendererTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SubObjectRendererTest.java @@ -149,13 +149,6 @@ void blobMemberSource_includesHashingUtils() { "HashingUtils.h is a source-only include, not a header include: " + h); } - @Test - void nonBlobSource_omitsHashingUtils() { - String c = renderAll().get("ContentBlock.cpp"); - assertFalse(c.contains("HashingUtils.h"), - "A sub-object without a blob member must not include HashingUtils.h: " + c); - } - @Test void memberlessShape_omitsPrivateSection() { // C2J emits the private: section only when the shape has members diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraitsTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraitsTest.java index cb15313dee2f..258c1d41361d 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraitsTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraitsTest.java @@ -123,12 +123,11 @@ void subObjectHeader_forwardDeclaresCborValueOnly() { // --- Source include/using sets must match C2J templates exactly. @Test - void requestSource_usesCborStreamingIncludesNotCborValue() { - // CborRequestSource.vm: only + ; NO - // (request payloads encode via the streaming CborEncoder, no CborValue DOM). + void requestSource_hasCborStreamingInclude() { + // Source includes are a per-protocol superset union; the request source carries at least + // the streaming . (Extra union members are inert; usings stay exact.) var inc = cbor.serdeIncludes(FileKind.REQUEST_SOURCE); assertTrue(inc.contains("aws/crt/cbor/Cbor.h"), inc.toString()); - assertFalse(inc.contains("aws/core/utils/cbor/CborValue.h"), inc.toString()); } @Test diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsIncludeSetTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsIncludeSetTest.java index f0555fd61808..d0b31058ebad 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsIncludeSetTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraitsIncludeSetTest.java @@ -30,8 +30,6 @@ void queryXml_requestSource_usesStringStreamNotXmlSerializer() { List inc = q.serdeIncludes(FileKind.REQUEST_SOURCE); assertTrue(inc.contains("aws/core/utils/StringUtils.h"), inc.toString()); assertTrue(inc.contains("aws/core/utils/memory/stl/AWSStringStream.h"), inc.toString()); - assertTrue(inc.stream().noneMatch(s -> s.contains("XmlSerializer")), inc.toString()); - assertTrue(inc.stream().noneMatch(s -> s.equals("utility")), inc.toString()); } @Test @@ -76,35 +74,28 @@ void eventHandler_usings_isSerdeNamespaceOnly() { } @Test - void initialResponseSource_excludesStringStream() { + void initialResponseSource_hasExpectedSerdeIncludes() { List json = new JsonProtocolTraits(Protocol.JSON).serdeIncludes(FileKind.INITIAL_RESPONSE_SOURCE); assertTrue(json.contains("aws/core/utils/json/JsonSerializer.h"), json.toString()); assertTrue(json.contains("aws/core/utils/UnreferencedParam.h"), json.toString()); - assertTrue(json.stream().noneMatch(s -> s.equals("aws/core/utils/memory/stl/AWSStringStream.h")), json.toString()); List cbor = new CborProtocolTraits().serdeIncludes(FileKind.INITIAL_RESPONSE_SOURCE); assertTrue(cbor.contains("aws/crt/cbor/Cbor.h"), cbor.toString()); assertTrue(cbor.contains("aws/core/utils/cbor/CborValue.h"), cbor.toString()); assertTrue(cbor.contains("aws/core/utils/UnreferencedParam.h"), cbor.toString()); - assertTrue(cbor.stream().noneMatch(s -> s.equals("aws/core/utils/memory/stl/AWSStringStream.h")), cbor.toString()); } @Test - void xmlInitialResponseSource_excludesResultOnlyIncludes() { + void xmlInitialResponseSource_hasExpectedIncludesAndUsingsExcludeLogging() { List restXml = new RestXmlProtocolTraits().serdeIncludes(FileKind.INITIAL_RESPONSE_SOURCE); assertTrue(restXml.contains("aws/core/utils/xml/XmlSerializer.h"), restXml.toString()); assertTrue(restXml.contains("aws/core/utils/UnreferencedParam.h"), restXml.toString()); - assertTrue(restXml.stream().noneMatch(s -> s.equals("aws/core/utils/memory/stl/AWSStringStream.h")), - restXml.toString()); List queryXml = new QueryXmlProtocolTraits(Protocol.QUERY_XML).serdeIncludes(FileKind.INITIAL_RESPONSE_SOURCE); assertTrue(queryXml.contains("aws/core/utils/UnreferencedParam.h"), queryXml.toString()); - assertTrue(queryXml.stream().noneMatch(s -> s.equals("aws/core/utils/memory/stl/AWSStringStream.h")), - queryXml.toString()); - assertTrue(queryXml.stream().noneMatch(s -> s.equals("aws/core/utils/logging/LogMacros.h")), - queryXml.toString()); + // Usings are held exact: the initial-response source must not open the Logging namespace. List restXmlUsings = new RestXmlProtocolTraits().serdeUsings(FileKind.INITIAL_RESPONSE_SOURCE); assertTrue(restXmlUsings.stream().noneMatch(s -> s.equals("Aws::Utils::Logging")), restXmlUsings.toString()); @@ -114,8 +105,10 @@ void xmlInitialResponseSource_excludesResultOnlyIncludes() { } @Test - void streamingResult_serdeIncludes_isEmpty() { - assertTrue(new RestXmlProtocolTraits().serdeIncludes(FileKind.STREAMING_RESULT_SOURCE).isEmpty()); + void streamingResult_serdeIncludes_returnsSourceUnion() { + // STREAMING_RESULT_SOURCE is a source kind, so it now returns the per-protocol source union. + List inc = new RestXmlProtocolTraits().serdeIncludes(FileKind.STREAMING_RESULT_SOURCE); + assertTrue(inc.contains("aws/core/utils/xml/XmlSerializer.h"), inc.toString()); } @Test diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSetsTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSetsTest.java index b80a15c8bc30..ae712da77367 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSetsTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/IncludeSetsTest.java @@ -92,4 +92,31 @@ void emitUsings_preservesOrder() { assertTrue(out.indexOf("using namespace Aws::Utils::Xml;") < out.indexOf("using namespace Aws::Utils;"), out); } + + @Test + void emitSourceIncludes_composesBaseAndSerdeUnionSortedDedupedBracketed() { + com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter w = + new com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter(); + // A representative source base plus the real JSON serde union for a source kind. The base + // repeats "utility" (also in the JSON union) to prove dedup across the two sources. + java.util.List base = java.util.List.of( + "aws/iam/model/GetRoleRequest.h", "utility"); + com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.ProtocolTraits json = + new com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.JsonProtocolTraits( + com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol.JSON); + IncludeSets.emitSourceIncludes(w, base, json, + com.amazonaws.util.awsclientsmithygenerator.generators.model.protocol.FileKind.REQUEST_SOURCE); + String out = w.toString(); + // Base member + every JSON source-union member appears, each exactly once, bracketed. + assertTrue(out.contains("#include "), out); + assertTrue(out.contains("#include "), out); + assertTrue(out.contains("#include "), out); + assertTrue(out.contains("#include "), out); + assertTrue(out.contains("#include "), out); + assertTrue(out.contains("#include "), out); + // dedup: emitted once despite appearing in both base and the union + assertEquals(out.indexOf(""), out.lastIndexOf(""), out); + // sorted CaseSensitive: the "aws/..." paths precede "utility" + assertTrue(out.indexOf("aws/core/utils/json/JsonSerializer.h") < out.indexOf(""), out); + } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ModelFileTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ModelFileTest.java index f24873ec9756..9df4243a81bb 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ModelFileTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ModelFileTest.java @@ -26,4 +26,24 @@ void modelNamespace_matchesHandWrittenTripleNest() { assertEquals(manual.toString(), viaHelper.toString()); } + + @Test + void modelNamespace_withProlog_emitsPrologInsideAwsBeforeNamespace() { + CppWriter manual = new CppWriter(); + manual.writeNamespaceOpen("Aws"); + manual.write("class Fwd;"); + manual.writeNamespaceOpen("S3"); + manual.writeNamespaceOpen("Model"); + manual.write("int x = 1;"); + manual.writeNamespaceClose("Model"); + manual.writeNamespaceClose("S3"); + manual.writeNamespaceClose("Aws"); + + CppWriter helper = new CppWriter(); + ModelFile.modelNamespace(helper, "S3", + () -> helper.write("class Fwd;"), + () -> helper.write("int x = 1;")); + + assertEquals(manual.toString(), helper.toString()); + } } From 2bc0fa5fea95117c5d89a57db40719a0d89eb4f3 Mon Sep 17 00:00:00 2001 From: sbaluja Date: Wed, 12 Aug 2026 15:38:54 -0400 Subject: [PATCH 04/19] fast fail serdeIncludes function --- .../model/protocol/CborProtocolTraits.java | 35 ++++++++++++------- .../model/protocol/JsonProtocolTraits.java | 33 +++++++++++------ .../protocol/QueryXmlProtocolTraits.java | 10 +++++- .../model/protocol/RestXmlProtocolTraits.java | 31 ++++++++++------ 4 files changed, 75 insertions(+), 34 deletions(-) diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraits.java index c4aa6857087d..05d204540187 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraits.java @@ -78,19 +78,30 @@ public void writeResultSerdeDecls(CppWriter writer, String exportMacro, String c @Override public java.util.List serdeIncludes(FileKind kind) { - // CborSubObjectHeader.vm / CborResultHeader.vm hard-include : the - // header signatures reference Aws::Crt::Cbor::CborDecoder / CborEncoder directly. - if (kind == FileKind.SUBOBJECT_HEADER || kind == FileKind.RESULT_HEADER) { - return java.util.List.of("aws/crt/cbor/Cbor.h"); + switch (kind) { + // CborSubObjectHeader.vm / CborResultHeader.vm hard-include : the + // header signatures reference Aws::Crt::Cbor::CborDecoder / CborEncoder directly. + case SUBOBJECT_HEADER: + case RESULT_HEADER: + return java.util.List.of("aws/crt/cbor/Cbor.h"); + // All source kinds share one union (supersets allowed). Usings are unchanged. + case SUBOBJECT_SOURCE: + case REQUEST_SOURCE: + case RESULT_SOURCE: + case STREAMING_RESULT_SOURCE: + case EVENT_HANDLER_SOURCE: + case INITIAL_RESPONSE_SOURCE: + return java.util.List.of( + "aws/crt/cbor/Cbor.h", + "aws/core/utils/cbor/CborValue.h", + "aws/core/utils/UnreferencedParam.h", + "aws/core/utils/memory/stl/AWSStringStream.h", + "aws/core/utils/HashingUtils.h", + "utility"); + default: + throw new UnsupportedOperationException( + "No serde includes defined for FileKind " + kind + " in CborProtocolTraits"); } - // All source kinds share one union (supersets allowed). Usings are unchanged. - return java.util.List.of( - "aws/crt/cbor/Cbor.h", - "aws/core/utils/cbor/CborValue.h", - "aws/core/utils/UnreferencedParam.h", - "aws/core/utils/memory/stl/AWSStringStream.h", - "aws/core/utils/HashingUtils.h", - "utility"); } @Override diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraits.java index 2e73779b3b99..f3ebf854a985 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraits.java @@ -81,18 +81,29 @@ public void writeResultSerdeDecls(CppWriter writer, String exportMacro, String c @Override public java.util.List serdeIncludes(FileKind kind) { - // Headers forward-declare JsonValue/JsonView; no serializer include. - if (kind == FileKind.SUBOBJECT_HEADER || kind == FileKind.RESULT_HEADER) { - return java.util.List.of(); + switch (kind) { + // Headers forward-declare JsonValue/JsonView; no serializer include. + case SUBOBJECT_HEADER: + case RESULT_HEADER: + return java.util.List.of(); + // All source kinds share one union (supersets allowed: a .cpp may carry an + // include it doesn't strictly use). Usings are unchanged; only #includes widen. + case SUBOBJECT_SOURCE: + case REQUEST_SOURCE: + case RESULT_SOURCE: + case STREAMING_RESULT_SOURCE: + case EVENT_HANDLER_SOURCE: + case INITIAL_RESPONSE_SOURCE: + return java.util.List.of( + "aws/core/utils/json/JsonSerializer.h", + "aws/core/utils/UnreferencedParam.h", + "aws/core/utils/memory/stl/AWSStringStream.h", + "aws/core/utils/HashingUtils.h", + "utility"); + default: + throw new UnsupportedOperationException( + "No serde includes defined for FileKind " + kind + " in JsonProtocolTraits"); } - // All source kinds share one union (supersets allowed: a .cpp may carry an - // include it doesn't strictly use). Usings are unchanged; only #includes widen. - return java.util.List.of( - "aws/core/utils/json/JsonSerializer.h", - "aws/core/utils/UnreferencedParam.h", - "aws/core/utils/memory/stl/AWSStringStream.h", - "aws/core/utils/HashingUtils.h", - "utility"); } @Override diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/QueryXmlProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/QueryXmlProtocolTraits.java index 62b45bc4ab97..7fa938f81486 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/QueryXmlProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/QueryXmlProtocolTraits.java @@ -93,7 +93,12 @@ public java.util.List serdeIncludes(FileKind kind) { case RESULT_HEADER: // Query/EC2 result headers forward-declare XmlDocument; no serde include. return java.util.List.of(); - default: + case SUBOBJECT_SOURCE: + case REQUEST_SOURCE: + case RESULT_SOURCE: + case STREAMING_RESULT_SOURCE: + case EVENT_HANDLER_SOURCE: + case INITIAL_RESPONSE_SOURCE: // All source kinds share one union (supersets allowed). Usings are unchanged. // No Query source arm carried , so the union omits it. return java.util.List.of( @@ -103,6 +108,9 @@ public java.util.List serdeIncludes(FileKind kind) { "aws/core/utils/StringUtils.h", "aws/core/utils/memory/stl/AWSStringStream.h", "aws/core/utils/HashingUtils.h"); + default: + throw new UnsupportedOperationException( + "No serde includes defined for FileKind " + kind + " in QueryXmlProtocolTraits"); } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RestXmlProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RestXmlProtocolTraits.java index e5bcfb44cadc..c4da525e0b3f 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RestXmlProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RestXmlProtocolTraits.java @@ -67,17 +67,28 @@ public void writeResultSerdeDecls(CppWriter writer, String exportMacro, String c @Override public java.util.List serdeIncludes(FileKind kind) { - // Sub-object and result headers forward-declare XmlNode/XmlDocument; no serializer include. - if (kind == FileKind.SUBOBJECT_HEADER || kind == FileKind.RESULT_HEADER) { - return java.util.List.of(); + switch (kind) { + // Sub-object and result headers forward-declare XmlNode/XmlDocument; no serializer include. + case SUBOBJECT_HEADER: + case RESULT_HEADER: + return java.util.List.of(); + // All source kinds share one union (supersets allowed). Usings are unchanged. + case SUBOBJECT_SOURCE: + case REQUEST_SOURCE: + case RESULT_SOURCE: + case STREAMING_RESULT_SOURCE: + case EVENT_HANDLER_SOURCE: + case INITIAL_RESPONSE_SOURCE: + return java.util.List.of( + "aws/core/utils/xml/XmlSerializer.h", + "aws/core/utils/memory/stl/AWSStringStream.h", + "aws/core/utils/UnreferencedParam.h", + "aws/core/utils/HashingUtils.h", + "utility"); + default: + throw new UnsupportedOperationException( + "No serde includes defined for FileKind " + kind + " in RestXmlProtocolTraits"); } - // All source kinds share one union (supersets allowed). Usings are unchanged. - return java.util.List.of( - "aws/core/utils/xml/XmlSerializer.h", - "aws/core/utils/memory/stl/AWSStringStream.h", - "aws/core/utils/UnreferencedParam.h", - "aws/core/utils/HashingUtils.h", - "utility"); } @Override From caf2e2d37dcb94f37d42b84949a7c550d689b40f Mon Sep 17 00:00:00 2001 From: sbaluja Date: Wed, 12 Aug 2026 15:43:02 -0400 Subject: [PATCH 05/19] Refactor MemberRenderer to be constructable and used as object Move MemberRenderer unit tests to instance API Migrate model renderers to MemberRenderer instance API Add MemberRenderer instance API; route static overloads through it Remove orphaned StructureShape import from CppTypeMapper --- .../generators/model/CppTypeMapper.java | 1 - .../generators/model/MemberOptions.java | 29 -- .../generators/model/MemberRenderer.java | 257 +++++------------- .../model/renderers/EventStreamRenderer.java | 7 +- .../model/renderers/RequestRenderer.java | 9 +- .../model/renderers/ResultRenderer.java | 20 +- .../model/renderers/SubObjectRenderer.java | 7 +- .../model/MemberRendererInstanceTest.java | 94 +++++++ .../model/MemberRendererOutputTest.java | 4 +- .../generators/model/MemberRendererTest.java | 63 ++--- 10 files changed, 209 insertions(+), 282 deletions(-) delete mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberOptions.java create mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererInstanceTest.java diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java index 82a86872e8cb..20f86fa28e7f 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java @@ -9,7 +9,6 @@ import software.amazon.smithy.model.shapes.MapShape; import software.amazon.smithy.model.shapes.MemberShape; import software.amazon.smithy.model.shapes.Shape; -import software.amazon.smithy.model.shapes.StructureShape; import software.amazon.smithy.model.traits.IdempotencyTokenTrait; import software.amazon.smithy.model.traits.SensitiveTrait; diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberOptions.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberOptions.java deleted file mode 100644 index 25f73019a7a6..000000000000 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberOptions.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -package com.amazonaws.util.awsclientsmithygenerator.generators.model; - -/** - * Options for {@link MemberRenderer#render}. Replaces the family of positional-boolean - * overloads so new rendering axes are added as a field here rather than as another overload. - */ -public final class MemberOptions { - private String exportMacro; - private String className; - private boolean emitHasBeenSet = true; - private String exclude = null; - private boolean wideIntegers = false; - - public MemberOptions exportMacro(String v) { this.exportMacro = v; return this; } - public MemberOptions className(String v) { this.className = v; return this; } - public MemberOptions emitHasBeenSet(boolean v) { this.emitHasBeenSet = v; return this; } - public MemberOptions exclude(String v) { this.exclude = v; return this; } - public MemberOptions wideIntegers(boolean v) { this.wideIntegers = v; return this; } - - public String exportMacro() { return exportMacro; } - public String className() { return className; } - public boolean emitHasBeenSet() { return emitHasBeenSet; } - public String exclude() { return exclude; } - public boolean wideIntegers() { return wideIntegers; } -} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java index 092a608bba88..71d5156b1ed8 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java @@ -11,7 +11,6 @@ import software.amazon.smithy.model.shapes.ListShape; import software.amazon.smithy.model.shapes.MemberShape; import software.amazon.smithy.model.shapes.Shape; -import software.amazon.smithy.model.shapes.StructureShape; import software.amazon.smithy.model.traits.DocumentationTrait; import software.amazon.smithy.model.traits.IdempotencyTokenTrait; @@ -26,157 +25,52 @@ */ public final class MemberRenderer { - private MemberRenderer() { + private final Model model; + private final Shape shape; + private final String className; + private final boolean emitHasBeenSet; + private boolean wideIntegers; + private String exclude; + + private MemberRenderer(Model model, Shape shape, String className, boolean emitHasBeenSet) { + this.model = model; + this.shape = shape; + this.className = className; + this.emitHasBeenSet = emitHasBeenSet; + this.wideIntegers = false; + this.exclude = null; } - /** - * Renders the top-level {@code RequestId} accessor group emitted by result headers: - * {@code GetRequestId} / templated {@code SetRequestId} / templated {@code WithRequestId}. - * Callers decide whether to emit it (Query/EC2 do not) and separately emit the - * {@code m_requestId} field and its {@code HasBeenSet} flag in the private section. - */ - public static void renderRequestIdAccessors(CppWriter writer, String className) { - writer.write(""); - writer.write("///@{"); - writer.write(""); - writer.write("inline const Aws::String& GetRequestId() const { return m_requestId; }"); - writer.write("template "); - writer.openBlock("void SetRequestId(RequestIdT&& value) {", "}", () -> { - writer.write("m_requestIdHasBeenSet = true;"); - writer.write("m_requestId = std::forward(value);"); - }); - writer.write("template "); - writer.openBlock("$L& WithRequestId(RequestIdT&& value) {", "}", className, () -> { - writer.write("SetRequestId(std::forward(value));"); - writer.write("return *this;"); - }); - writer.write("///@}"); - } - - /** - * Writes the public accessor methods for all members of a structure shape. - * - *

    For each member, generates: - *

      - *
    • Doxygen group markers ({@code ///@\{} and {@code ///@\}})
    • - *
    • Documentation comment (if present)
    • - *
    • Getter (const ref for non-primitives, value for primitives)
    • - *
    • HasBeenSet check
    • - *
    • Templated Set method
    • - *
    • Templated With method (fluent)
    • - *
    • Templated Add method (list/map members only)
    • - *
    - * - * @param writer the CppWriter to write to - * @param shape the structure shape whose members to render - * @param model the model (for resolving member targets) - * @param exportMacro the export macro (e.g., "AWS_KINESIS_API") - * @param className the C++ class name (e.g., "ChildShard") - */ - public static void renderPublicSection(CppWriter writer, Shape shape, - Model model, String exportMacro, String className) { - render(writer, shape, model, - new MemberOptions().exportMacro(exportMacro).className(className).emitHasBeenSet(true)); + /** Renderer for a request / sub-object / event structure: emits {@code HasBeenSet} accessors. */ + public static MemberRenderer forStructure(Model model, Shape shape, String className) { + return new MemberRenderer(model, shape, className, true); } - /** - * Like {@link #renderPublicSection(CppWriter, Shape, Model, String, String)} but widens - * {@code integer} members to {@code int64_t} when {@code wideIntegers} is set (CBOR sub-objects). - */ - public static void renderPublicSection(CppWriter writer, Shape shape, - Model model, String exportMacro, String className, - boolean wideIntegers) { - render(writer, shape, model, new MemberOptions() - .exportMacro(exportMacro).className(className).emitHasBeenSet(true).wideIntegers(wideIntegers)); + /** Renderer for a result structure: never emits {@code HasBeenSet} accessors. */ + public static MemberRenderer forResult(Model model, Shape shape, String className) { + return new MemberRenderer(model, shape, className, false); } - /** - * Writes public accessor methods for result shapes. Result classes never emit - * {@code HasBeenSet()} accessors: every protocol's result header sets - * {@code useRequiredField=false} in C2J (only sub-object / request headers set it true). - * - * @param writer the CppWriter to write to - * @param shape the structure shape whose members to render - * @param model the model (for resolving member targets) - * @param exportMacro the export macro (e.g., "AWS_KINESIS_API") - * @param className the C++ class name (e.g., "GetItemResult") - */ - public static void renderPublicSectionForResult(CppWriter writer, StructureShape shape, - Model model, String exportMacro, String className, - boolean wideIntegers) { - render(writer, shape, model, new MemberOptions() - .exportMacro(exportMacro).className(className).emitHasBeenSet(false).wideIntegers(wideIntegers)); + /** Widen {@code integer} members to {@code int64_t} (CBOR sub-objects / events). */ + public MemberRenderer wideIntegers(boolean value) { + this.wideIntegers = value; + return this; } /** - * Renders result accessors for every member except {@code excludeMemberName}. Used by - * streaming results, whose {@code @httpPayload} member is rendered separately as a - * {@code GetBody()} / {@code ReplaceBody} pair. Like {@link #renderPublicSectionForResult}, - * result members never get {@code HasBeenSet()} accessors. + * Skip {@code memberName} across all fragments. Streaming results render their + * {@code @httpPayload} member separately as a {@code GetBody()} / {@code ReplaceBody} pair. */ - public static void renderPublicSectionForResultExcluding(CppWriter writer, StructureShape shape, - Model model, String exportMacro, String className, - String excludeMemberName, boolean wideIntegers) { - render(writer, shape, model, new MemberOptions() - .exportMacro(exportMacro).className(className).emitHasBeenSet(false) - .exclude(excludeMemberName).wideIntegers(wideIntegers)); - } - - /** - * Single entry point for rendering a structure's public accessor methods. - * See {@link MemberOptions} for the rendering axes. - */ - public static void render(CppWriter writer, Shape shape, Model model, MemberOptions opts) { - renderMembers(writer, shape, model, opts.exportMacro(), opts.className(), - opts.emitHasBeenSet(), opts.exclude(), opts.wideIntegers()); - } - - /** Writes data member declarations, skipping {@code excludeMemberName}. */ - public static void renderPrivateDataMembersExcluding(CppWriter writer, StructureShape shape, - Model model, String excludeMemberName) { - renderPrivateDataMembersExcluding(writer, shape, model, excludeMemberName, false); - } - - /** Data member declarations excluding one member, widening {@code integer} when requested. */ - public static void renderPrivateDataMembersExcluding(CppWriter writer, StructureShape shape, - Model model, String excludeMemberName, - boolean wideIntegers) { - java.util.List> entries = - new java.util.ArrayList<>(shape.getAllMembers().entrySet()); - entries.removeIf(e -> e.getKey().equals(excludeMemberName)); - for (int i = 0; i < entries.size(); i++) { - Map.Entry entry = entries.get(i); - writeDataMember(writer, entry.getValue(), entry.getKey(), model, wideIntegers); - if (i < entries.size() - 1) { - writer.write(""); - } - } - } - - /** Writes HasBeenSet flags, skipping {@code excludeMemberName}. */ - public static void renderPrivateHasBeenSetFlagsExcluding(CppWriter writer, StructureShape shape, - Model model, String excludeMemberName) { - for (Map.Entry entry : shape.getAllMembers().entrySet()) { - if (entry.getKey().equals(excludeMemberName)) { - continue; - } - writeHasBeenSetFlag(writer, entry.getValue(), entry.getKey()); - } + public MemberRenderer excluding(String memberName) { + this.exclude = memberName; + return this; } - /** - * Shared member-rendering implementation with an optional excluded member. Streaming - * results emit their {@code @httpPayload} member via a dedicated {@code GetBody()} / - * {@code ReplaceBody} accessor pair, so that member is skipped here. - * - * @param excludeMemberName member name to skip, or {@code null} to render all members - */ - private static void renderMembers(CppWriter writer, Shape shape, - Model model, String exportMacro, String className, - boolean emitHasBeenSet, String excludeMemberName, boolean wideIntegers) { + /** Public Get/Set/With/Add accessor group for every (non-excluded) member. */ + public void renderPublicAccessors(CppWriter writer) { java.util.List> members = new java.util.ArrayList<>(shape.getAllMembers().entrySet()); - members.removeIf(e -> e.getKey().equals(excludeMemberName)); + members.removeIf(e -> e.getKey().equals(exclude)); for (int i = 0; i < members.size(); i++) { Map.Entry entry = members.get(i); String memberName = entry.getKey(); @@ -184,10 +78,6 @@ private static void renderMembers(CppWriter writer, Shape shape, Shape targetShape = model.expectShape(member.getTarget()); String cppType = CppTypeMapper.getCppType(targetShape, model, wideIntegers); String fieldName = CppNames.fieldName(memberName); - // Method names and template params use the capitalized member name to match the - // legacy C2J convention (e.g. member "extendedKeyUsage" -> GetExtendedKeyUsage, - // ExtendedKeyUsageHasBeenSet, template param ExtendedKeyUsageT). Field names keep - // the decapitalized form (m_extendedKeyUsage). String methodName = capitalize(memberName); String templateParam = methodName + "T"; @@ -199,9 +89,6 @@ private static void renderMembers(CppWriter writer, Shape shape, writer.write(""); } - // Getter. Documents are special-cased to return Aws::Utils::DocumentView by value - // (the field and setter keep Aws::Utils::Document), matching C2J's - // ModelClassMembersAndInlines.vm $returnType handling. if (targetShape.isDocumentShape()) { writer.write("inline Aws::Utils::DocumentView Get$L() const { return $L; }", methodName, fieldName); } else if (isPrimitive(targetShape) || targetShape.isEnumShape()) { @@ -210,7 +97,6 @@ private static void renderMembers(CppWriter writer, Shape shape, writer.write("inline const $L& Get$L() const { return $L; }", cppType, methodName, fieldName); } - // HasBeenSet (only for non-result shapes) if (emitHasBeenSet) { writer.write("inline bool $LHasBeenSet() const { return $LHasBeenSet; }", methodName, fieldName); } @@ -263,8 +149,6 @@ private static void renderMembers(CppWriter writer, Shape shape, targetShape.asMapShape().get().getValue().getTarget()); String keyType = CppTypeMapper.getCppType(keyShape, model, wideIntegers); String valueType = CppTypeMapper.getCppType(valueShape, model, wideIntegers); - // C2J uses a templated perfect-forwarding Add only when BOTH key and value - // are non-primitive AND non-enum; otherwise a plain by-value Add. boolean bothForwardable = !isByValueType(keyShape) && !isByValueType(valueShape); if (bothForwardable) { String keyParam = methodName + "KeyT"; @@ -292,43 +176,11 @@ private static void renderMembers(CppWriter writer, Shape shape, } } - /** - * Writes the private member fields and HasBeenSet flags for a structure. - * - *

    Layout: - *

      - *
    1. Data members (with blank line between each), primitives get brace-initialized defaults
    2. - *
    3. HasBeenSet boolean flags grouped together at the end
    4. - *
    - * - * @param writer the CppWriter to write to - * @param shape the structure shape whose members to render - * @param model the model (for resolving member targets) - */ - public static void renderPrivateSection(CppWriter writer, Shape shape, Model model) { - renderPrivateSection(writer, shape, model, false); - } - - /** - * Like {@link #renderPrivateSection(CppWriter, Shape, Model)} but widens {@code integer} - * data members to {@code int64_t} when {@code wideIntegers} is set (CBOR sub-objects). - */ - public static void renderPrivateSection(CppWriter writer, Shape shape, Model model, boolean wideIntegers) { - renderPrivateDataMembers(writer, shape, model, wideIntegers); - renderPrivateHasBeenSetFlags(writer, shape, model); - } - - /** - * Writes only the data member declarations (with blank lines between each). - */ - public static void renderPrivateDataMembers(CppWriter writer, Shape shape, Model model) { - renderPrivateDataMembers(writer, shape, model, false); - } - - /** Data member declarations, widening {@code integer} to {@code int64_t} when requested. */ - public static void renderPrivateDataMembers(CppWriter writer, Shape shape, Model model, boolean wideIntegers) { + /** Private data member declarations (blank line between each), skipping the excluded member. */ + public void renderDataMembers(CppWriter writer) { java.util.List> entries = new java.util.ArrayList<>(shape.getAllMembers().entrySet()); + entries.removeIf(e -> e.getKey().equals(exclude)); for (int i = 0; i < entries.size(); i++) { Map.Entry entry = entries.get(i); writeDataMember(writer, entry.getValue(), entry.getKey(), model, wideIntegers); @@ -338,15 +190,46 @@ public static void renderPrivateDataMembers(CppWriter writer, Shape shape, Model } } - /** - * Writes only the HasBeenSet boolean flags (one per member, no blank lines between). - */ - public static void renderPrivateHasBeenSetFlags(CppWriter writer, Shape shape, Model model) { + /** Private {@code HasBeenSet} flags (one per member, no blank lines), skipping the excluded member. */ + public void renderHasBeenSetFlags(CppWriter writer) { for (Map.Entry entry : shape.getAllMembers().entrySet()) { + if (entry.getKey().equals(exclude)) { + continue; + } writeHasBeenSetFlag(writer, entry.getValue(), entry.getKey()); } } + /** Data members immediately followed by the {@code HasBeenSet} flags (no separating blank line). */ + public void renderPrivateSection(CppWriter writer) { + renderDataMembers(writer); + renderHasBeenSetFlags(writer); + } + + /** + * Renders the top-level {@code RequestId} accessor group emitted by result headers: + * {@code GetRequestId} / templated {@code SetRequestId} / templated {@code WithRequestId}. + * Callers decide whether to emit it (Query/EC2 do not) and separately emit the + * {@code m_requestId} field and its {@code HasBeenSet} flag in the private section. + */ + public static void renderRequestIdAccessors(CppWriter writer, String className) { + writer.write(""); + writer.write("///@{"); + writer.write(""); + writer.write("inline const Aws::String& GetRequestId() const { return m_requestId; }"); + writer.write("template "); + writer.openBlock("void SetRequestId(RequestIdT&& value) {", "}", () -> { + writer.write("m_requestIdHasBeenSet = true;"); + writer.write("m_requestId = std::forward(value);"); + }); + writer.write("template "); + writer.openBlock("$L& WithRequestId(RequestIdT&& value) {", "}", className, () -> { + writer.write("SetRequestId(std::forward(value));"); + writer.write("return *this;"); + }); + writer.write("///@}"); + } + /** * Writes a single private data member declaration. {@code @idempotencyToken} members are * brace-initialized with {@code Aws::Utils::UUID::PseudoRandomUUID()} so a caller who omits diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EventStreamRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EventStreamRenderer.java index fcc5283a4c67..83420c3f6b42 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EventStreamRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EventStreamRenderer.java @@ -460,13 +460,14 @@ private void renderInitialResponse(CppWriterDelegator writerDelegator, String op // Accessors + private section for the result's non-streaming members. A memberless // InitialResponse ends right after its serde decls (no private:), matching C2J. if (hasMembers) { - boolean wideIntegers = ctx.protocolTraits().widensIntegers(); + MemberRenderer members = MemberRenderer.forStructure(ctx.model(), shape, className) + .wideIntegers(ctx.protocolTraits().widensIntegers()); writer.write(""); - MemberRenderer.renderPublicSection(writer, shape, ctx.model(), ctx.exportMacro(), className, wideIntegers); + members.renderPublicAccessors(writer); writer.dedent(); writer.write("private:"); writer.indent(); - MemberRenderer.renderPrivateSection(writer, shape, ctx.model(), wideIntegers); + members.renderPrivateSection(writer); } }); writer.write(""); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java index a45808469c58..515c7bd1ad7e 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java @@ -193,7 +193,8 @@ private void renderHeader(CppWriterDelegator writerDelegator, } writer.write(""); - MemberRenderer.renderPublicSection(writer, shape, ctx.model(), ctx.exportMacro(), className); + MemberRenderer members = MemberRenderer.forStructure(ctx.model(), shape, className); + members.renderPublicAccessors(writer); eventStreamMember.ifPresent(m -> renderEventStreamMemberAccessor(writer, className, rawShape, m)); @@ -205,18 +206,18 @@ private void renderHeader(CppWriterDelegator writerDelegator, if (streamingResponse) { // Mainline places the event-stream member, then the handler/decoder, after // the data members and before the HasBeenSet flags. - MemberRenderer.renderPrivateDataMembers(writer, shape, ctx.model()); + members.renderDataMembers(writer); eventStreamMember.ifPresent(m -> writer.write("std::shared_ptr<$1L> m_$2L;", eventStreamUnionType(rawShape, m), CppNames.decapitalize(m))); String handlerType = operation.getId().getName() + "Handler"; writer.write("$1L m_handler;", handlerType); writer.write("Aws::Utils::Event::EventStreamDecoder m_decoder{Utils::Event::EventStreamDecoder(&m_handler)};"); writer.write(""); - MemberRenderer.renderPrivateHasBeenSetFlags(writer, shape, ctx.model()); + members.renderHasBeenSetFlags(writer); eventStreamMember.ifPresent(m -> writer.write("bool m_$1LHasBeenSet = false;", CppNames.decapitalize(m))); } else { - MemberRenderer.renderPrivateSection(writer, shape, ctx.model()); + members.renderPrivateSection(writer); } } }); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ResultRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ResultRenderer.java index 9509f62a066b..dbd565fe9b57 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ResultRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/ResultRenderer.java @@ -104,8 +104,9 @@ private void renderHeader(CppWriterDelegator writerDelegator, ctx.protocolTraits().writeResultSerdeDecls(writer, ctx.exportMacro(), className); writer.write(""); - MemberRenderer.renderPublicSectionForResult(writer, shape, ctx.model(), ctx.exportMacro(), className, - ctx.protocolTraits().widensIntegers()); + MemberRenderer members = MemberRenderer.forResult(ctx.model(), shape, className) + .wideIntegers(ctx.protocolTraits().widensIntegers()); + members.renderPublicAccessors(writer); boolean topLevelRequestId = ctx.protocolTraits().resultHasTopLevelRequestId(); if (topLevelRequestId) { @@ -118,7 +119,7 @@ private void renderHeader(CppWriterDelegator writerDelegator, writer.dedent(); writer.write("private:"); writer.indent(); - MemberRenderer.renderPrivateDataMembers(writer, shape, ctx.model(), ctx.protocolTraits().widensIntegers()); + members.renderDataMembers(writer); if (topLevelRequestId) { // The blank line separates the modeled members from the m_requestId group; // C2J omits it (and m_requestId) for Query/EC2 results. @@ -126,7 +127,7 @@ private void renderHeader(CppWriterDelegator writerDelegator, writer.write("Aws::String m_requestId;"); } writer.write("Aws::Http::HttpResponseCode m_HttpResponseCode;"); - MemberRenderer.renderPrivateHasBeenSetFlags(writer, shape, ctx.model()); + members.renderHasBeenSetFlags(writer); if (topLevelRequestId) { writer.write("bool m_requestIdHasBeenSet = false;"); } @@ -223,8 +224,10 @@ private void renderStreamingHeader(CppWriterDelegator writerDelegator, + "$L = Aws::Utils::Stream::ResponseStream(body); }", streamField); writer.write("///@}"); - MemberRenderer.renderPublicSectionForResultExcluding(writer, shape, ctx.model(), ctx.exportMacro(), - className, streamMember, ctx.protocolTraits().widensIntegers()); + MemberRenderer members = MemberRenderer.forResult(ctx.model(), shape, className) + .wideIntegers(ctx.protocolTraits().widensIntegers()) + .excluding(streamMember); + members.renderPublicAccessors(writer); MemberRenderer.renderRequestIdAccessors(writer, className); @@ -235,13 +238,12 @@ private void renderStreamingHeader(CppWriterDelegator writerDelegator, writer.write("private:"); writer.indent(); writer.write("Aws::Utils::Stream::ResponseStream $L{};", streamField); - MemberRenderer.renderPrivateDataMembersExcluding(writer, shape, ctx.model(), streamMember, - ctx.protocolTraits().widensIntegers()); + members.renderDataMembers(writer); writer.write(""); writer.write("Aws::String m_requestId;"); writer.write("Aws::Http::HttpResponseCode m_HttpResponseCode;"); writer.write("bool $LHasBeenSet = false;", streamField); - MemberRenderer.renderPrivateHasBeenSetFlagsExcluding(writer, shape, ctx.model(), streamMember); + members.renderHasBeenSetFlags(writer); writer.write("bool m_requestIdHasBeenSet = false;"); }); writer.write(""); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/SubObjectRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/SubObjectRenderer.java index 8b4f296bf3ea..e16388688fc4 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/SubObjectRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/SubObjectRenderer.java @@ -83,13 +83,14 @@ private void renderHeader(CppWriterDelegator writerDelegator, Shape shape) { // and no private: section (ModelClassMembersAndInlines.vm gates both on // $shape.members.size() > 0). if (!shape.getAllMembers().isEmpty()) { - boolean wideIntegers = ctx.protocolTraits().widensIntegers(); + MemberRenderer members = MemberRenderer.forStructure(ctx.model(), shape, className) + .wideIntegers(ctx.protocolTraits().widensIntegers()); writer.write(""); - MemberRenderer.renderPublicSection(writer, shape, ctx.model(), ctx.exportMacro(), className, wideIntegers); + members.renderPublicAccessors(writer); writer.dedent(); writer.write("private:"); writer.indent(); - MemberRenderer.renderPrivateSection(writer, shape, ctx.model(), wideIntegers); + members.renderPrivateSection(writer); } }); writer.write(""); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererInstanceTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererInstanceTest.java new file mode 100644 index 000000000000..cd0b74f630ed --- /dev/null +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererInstanceTest.java @@ -0,0 +1,94 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.model; + +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; +import org.junit.jupiter.api.Test; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.IntegerShape; +import software.amazon.smithy.model.shapes.StringShape; +import software.amazon.smithy.model.shapes.StructureShape; + +import static org.junit.jupiter.api.Assertions.*; + +class MemberRendererInstanceTest { + + private static Model model(StructureShape shape, software.amazon.smithy.model.shapes.Shape... rest) { + Model.Builder b = Model.builder().addShape(shape); + for (software.amazon.smithy.model.shapes.Shape s : rest) { + b.addShape(s); + } + return b.build(); + } + + @Test + void forStructure_publicAccessors_emitsHasBeenSet() { + StringShape str = StringShape.builder().id("com.example#String").build(); + StructureShape shape = StructureShape.builder() + .id("com.example#MyShape").addMember("Name", str.getId()).build(); + CppWriter w = new CppWriter(); + MemberRenderer.forStructure(model(shape, str), shape, "MyShape").renderPublicAccessors(w); + String out = w.toString(); + assertTrue(out.contains("inline const Aws::String& GetName() const"), out); + assertTrue(out.contains("inline bool NameHasBeenSet() const"), out); + assertTrue(out.contains("MyShape& WithName(NameT&& value)"), out); + } + + @Test + void forResult_publicAccessors_omitsHasBeenSet() { + StringShape str = StringShape.builder().id("com.example#String").build(); + StructureShape shape = StructureShape.builder() + .id("com.example#MyResult").addMember("Name", str.getId()).build(); + CppWriter w = new CppWriter(); + MemberRenderer.forResult(model(shape, str), shape, "MyResult").renderPublicAccessors(w); + String out = w.toString(); + assertTrue(out.contains("inline const Aws::String& GetName() const"), out); + assertFalse(out.contains("NameHasBeenSet() const"), "results must not emit HasBeenSet: " + out); + } + + @Test + void excluding_dropsMemberFromAllFragments() { + StringShape str = StringShape.builder().id("com.example#String").build(); + StructureShape shape = StructureShape.builder() + .id("com.example#MyShape") + .addMember("Keep", str.getId()) + .addMember("Drop", str.getId()) + .build(); + MemberRenderer r = MemberRenderer.forResult(model(shape, str), shape, "MyShape").excluding("Drop"); + CppWriter pub = new CppWriter(); r.renderPublicAccessors(pub); + CppWriter data = new CppWriter(); r.renderDataMembers(data); + CppWriter flags = new CppWriter(); r.renderHasBeenSetFlags(flags); + assertFalse(pub.toString().contains("GetDrop"), pub.toString()); + assertFalse(data.toString().contains("m_drop"), data.toString()); + assertFalse(flags.toString().contains("m_dropHasBeenSet"), flags.toString()); + assertTrue(pub.toString().contains("GetKeep"), pub.toString()); + } + + @Test + void wideIntegers_widensIntegerDataMemberToInt64() { + IntegerShape intShape = IntegerShape.builder().id("com.example#Integer").build(); + StructureShape shape = StructureShape.builder() + .id("com.example#MyShape").addMember("Count", intShape.getId()).build(); + CppWriter narrow = new CppWriter(); + MemberRenderer.forStructure(model(shape, intShape), shape, "MyShape").renderDataMembers(narrow); + CppWriter wide = new CppWriter(); + MemberRenderer.forStructure(model(shape, intShape), shape, "MyShape") + .wideIntegers(true).renderDataMembers(wide); + assertTrue(narrow.toString().contains("int m_count{0};"), narrow.toString()); + assertTrue(wide.toString().contains("long long m_count{0};") || wide.toString().contains("int64_t m_count{0};"), + "wideIntegers must widen the integer field: " + wide.toString()); + } + + @Test + void renderPrivateSection_dataMembersPrecedeHasBeenSetFlags() { + StringShape str = StringShape.builder().id("com.example#String").build(); + StructureShape shape = StructureShape.builder() + .id("com.example#MyShape").addMember("Name", str.getId()).build(); + CppWriter w = new CppWriter(); + MemberRenderer.forStructure(model(shape, str), shape, "MyShape").renderPrivateSection(w); + String out = w.toString(); + assertTrue(out.indexOf("Aws::String m_name;") < out.indexOf("bool m_nameHasBeenSet = false;"), out); + } +} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererOutputTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererOutputTest.java index 794e7da4be25..1bfad50e3ec6 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererOutputTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererOutputTest.java @@ -34,7 +34,7 @@ void fullOutput_matchesExpectedPattern() { Model model = Model.builder().addShapes(str, list, nested, shape).build(); CppWriter pubWriter = new CppWriter(); - MemberRenderer.renderPublicSection(pubWriter, shape, model, "AWS_KINESIS_API", "ChildShard"); + MemberRenderer.forStructure(model, shape, "ChildShard").renderPublicAccessors(pubWriter); String pubOutput = pubWriter.toString(); System.out.println("=== PUBLIC ==="); System.out.println(pubOutput); @@ -60,7 +60,7 @@ void fullOutput_matchesExpectedPattern() { // Private section CppWriter privWriter = new CppWriter(); - MemberRenderer.renderPrivateSection(privWriter, shape, model); + MemberRenderer.forStructure(model, shape, null).renderPrivateSection(privWriter); String privOutput = privWriter.toString(); System.out.println("=== PRIVATE ==="); System.out.println(privOutput); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererTest.java index 8699f0ad7be2..7bd57f1e0ccb 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererTest.java @@ -28,7 +28,7 @@ void renderPublicSection_stringMember_producesGetSetWith() { .build(); Model model = Model.builder().addShapes(str, shape).build(); CppWriter writer = new CppWriter(); - MemberRenderer.renderPublicSection(writer, shape, model, "AWS_TEST_API", "MyShape"); + MemberRenderer.forStructure(model, shape, "MyShape").renderPublicAccessors(writer); String output = writer.toString(); assertTrue(output.contains("inline const Aws::String& GetName() const"), "Missing getter: " + output); assertTrue(output.contains("inline bool NameHasBeenSet() const"), "Missing HasBeenSet: " + output); @@ -48,7 +48,7 @@ void renderPublicSection_lowercaseMember_capitalizesMethodNames() { .build(); Model model = Model.builder().addShapes(str, shape).build(); CppWriter writer = new CppWriter(); - MemberRenderer.renderPublicSection(writer, shape, model, "AWS_TEST_API", "MyShape"); + MemberRenderer.forStructure(model, shape, "MyShape").renderPublicAccessors(writer); String output = writer.toString(); assertTrue(output.contains("GetExtendedKeyUsage() const"), "Getter should be capitalized: " + output); assertTrue(output.contains("ExtendedKeyUsageHasBeenSet() const"), "HasBeenSet should be capitalized: " + output); @@ -73,7 +73,7 @@ void renderPublicSection_listMember_producesAddMethod() { .build(); Model model = Model.builder().addShapes(str, list, shape).build(); CppWriter writer = new CppWriter(); - MemberRenderer.renderPublicSection(writer, shape, model, "AWS_TEST_API", "MyShape"); + MemberRenderer.forStructure(model, shape, "MyShape").renderPublicAccessors(writer); String output = writer.toString(); assertTrue(output.contains("MyShape& AddItems(ItemsT&& value)"), "Missing Add: " + output); assertTrue(output.contains("m_items.emplace_back(std::forward(value))"), "Missing emplace_back: " + output); @@ -92,7 +92,7 @@ void renderPublicSection_listMember_addTemplateDefaultIsElementType() { .build(); Model model = Model.builder().addShapes(str, list, shape).build(); CppWriter writer = new CppWriter(); - MemberRenderer.renderPublicSection(writer, shape, model, "AWS_TEST_API", "MyShape"); + MemberRenderer.forStructure(model, shape, "MyShape").renderPublicAccessors(writer); String output = writer.toString(); // The Add method's template default should be the element type, not the list type assertTrue(output.contains("template \nMyShape& AddItems"), @@ -114,7 +114,7 @@ void renderPublicSection_listOfPrimitive_addIsByValue() { .build(); Model model = Model.builder().addShapes(intShape, list, shape).build(); CppWriter writer = new CppWriter(); - MemberRenderer.renderPublicSection(writer, shape, model, "AWS_TEST_API", "MyShape"); + MemberRenderer.forStructure(model, shape, "MyShape").renderPublicAccessors(writer); String output = writer.toString(); assertTrue(output.contains("inline MyShape& AddCounts(int value)"), "List of primitive should get by-value Add: " + output); @@ -141,7 +141,7 @@ void renderPublicSection_mapWithPrimitiveValue_addIsByValue() { .build(); Model model = Model.builder().addShapes(str, intShape, map, shape).build(); CppWriter writer = new CppWriter(); - MemberRenderer.renderPublicSection(writer, shape, model, "AWS_TEST_API", "MyShape"); + MemberRenderer.forStructure(model, shape, "MyShape").renderPublicAccessors(writer); String output = writer.toString(); assertTrue(output.contains("MyShape& AddSummaryMap(Aws::String key, int value)"), "Map with primitive value should get by-value Add: " + output); @@ -167,7 +167,7 @@ void renderPublicSection_mapWithNonPrimitiveKeyAndValue_addIsTemplated() { .build(); Model model = Model.builder().addShapes(str, valueStruct, map, shape).build(); CppWriter writer = new CppWriter(); - MemberRenderer.renderPublicSection(writer, shape, model, "AWS_TEST_API", "MyShape"); + MemberRenderer.forStructure(model, shape, "MyShape").renderPublicAccessors(writer); String output = writer.toString(); assertTrue(output.contains("MyShape& AddThingMap(ThingMapKeyT&& key, ThingMapValueT&& value)"), "Map with non-primitive key/value should get templated Add: " + output); @@ -188,7 +188,7 @@ void renderPublicSection_documentMember_getterReturnsDocumentViewByValue() { .build(); Model model = Model.builder().addShapes(doc, shape).build(); CppWriter writer = new CppWriter(); - MemberRenderer.renderPublicSection(writer, shape, model, "AWS_TEST_API", "MyShape"); + MemberRenderer.forStructure(model, shape, "MyShape").renderPublicAccessors(writer); String output = writer.toString(); assertTrue(output.contains("inline Aws::Utils::DocumentView GetJson() const { return m_json; }"), "Document getter must return DocumentView by value: " + output); @@ -209,7 +209,7 @@ void renderPublicSection_documentMember_privateFieldIsDocument() { .build(); Model model = Model.builder().addShapes(doc, shape).build(); CppWriter writer = new CppWriter(); - MemberRenderer.renderPrivateSection(writer, shape, model); + MemberRenderer.forStructure(model, shape, null).renderPrivateSection(writer); String output = writer.toString(); assertTrue(output.contains("Aws::Utils::Document m_json;"), "Document field must be Aws::Utils::Document: " + output); @@ -228,14 +228,14 @@ void renderPublicSection_sensitiveBlobMember_usesCryptoBuffer() { .build(); Model model = Model.builder().addShapes(sensitive, shape).build(); CppWriter pub = new CppWriter(); - MemberRenderer.renderPublicSection(pub, shape, model, "AWS_TEST_API", "MyShape"); + MemberRenderer.forStructure(model, shape, "MyShape").renderPublicAccessors(pub); String pubOut = pub.toString(); assertTrue(pubOut.contains("inline const Aws::Utils::CryptoBuffer& GetBytes() const"), "Sensitive blob getter must be CryptoBuffer: " + pubOut); assertTrue(pubOut.contains("template "), "Sensitive blob setter template default must be CryptoBuffer: " + pubOut); CppWriter priv = new CppWriter(); - MemberRenderer.renderPrivateSection(priv, shape, model); + MemberRenderer.forStructure(model, shape, null).renderPrivateSection(priv); assertTrue(priv.toString().contains("Aws::Utils::CryptoBuffer m_bytes{};"), "Sensitive blob field must be CryptoBuffer: " + priv); } @@ -249,7 +249,7 @@ void renderPublicSection_primitiveGetter_returnsByValue() { .build(); Model model = Model.builder().addShapes(intShape, shape).build(); CppWriter writer = new CppWriter(); - MemberRenderer.renderPublicSection(writer, shape, model, "AWS_TEST_API", "MyShape"); + MemberRenderer.forStructure(model, shape, "MyShape").renderPublicAccessors(writer); String output = writer.toString(); // Primitive getter should return by value, not const ref assertTrue(output.contains("inline int GetCount() const"), "Primitive should return by value: " + output); @@ -265,7 +265,7 @@ void renderPublicSection_doxygenGroupMarkers() { .build(); Model model = Model.builder().addShapes(str, shape).build(); CppWriter writer = new CppWriter(); - MemberRenderer.renderPublicSection(writer, shape, model, "AWS_TEST_API", "MyShape"); + MemberRenderer.forStructure(model, shape, "MyShape").renderPublicAccessors(writer); String output = writer.toString(); assertTrue(output.contains("///@{"), "Missing doxygen open: " + output); assertTrue(output.contains("///@}"), "Missing doxygen close: " + output); @@ -282,7 +282,7 @@ void renderPrivateSection_primitiveMembers_haveDefaultValues() { .build(); Model model = Model.builder().addShapes(intShape, boolShape, shape).build(); CppWriter writer = new CppWriter(); - MemberRenderer.renderPrivateSection(writer, shape, model); + MemberRenderer.forStructure(model, shape, null).renderPrivateSection(writer); String output = writer.toString(); assertTrue(output.contains("int m_count{0}"), "Missing int default: " + output); assertTrue(output.contains("bool m_enabled{false}"), "Missing bool default: " + output); @@ -299,7 +299,7 @@ void renderPrivateSection_nonPrimitiveMembers_noDefaultValue() { .build(); Model model = Model.builder().addShapes(str, shape).build(); CppWriter writer = new CppWriter(); - MemberRenderer.renderPrivateSection(writer, shape, model); + MemberRenderer.forStructure(model, shape, null).renderPrivateSection(writer); String output = writer.toString(); assertTrue(output.contains("Aws::String m_name;"), "Missing string field: " + output); assertFalse(output.contains("m_name{"), "String should NOT have brace init: " + output); @@ -322,7 +322,7 @@ void renderPrivateSection_idempotencyTokenMember_initializesWithPseudoRandomUuid .build(); Model model = Model.builder().addShapes(str, shape).build(); CppWriter writer = new CppWriter(); - MemberRenderer.renderPrivateSection(writer, shape, model); + MemberRenderer.forStructure(model, shape, null).renderPrivateSection(writer); String output = writer.toString(); assertTrue(output.contains("Aws::String m_clientToken{Aws::Utils::UUID::PseudoRandomUUID()};"), "Idempotency token should be initialized with PseudoRandomUUID: " + output); @@ -345,12 +345,12 @@ void renderPrivateDataMembersExcluding_idempotencyTokenMember_initializesWithPse .build(); Model model = Model.builder().addShapes(str, shape).build(); CppWriter writer = new CppWriter(); - MemberRenderer.renderPrivateDataMembersExcluding(writer, shape, model, "other"); + MemberRenderer.forStructure(model, shape, null).excluding("other").renderDataMembers(writer); String dataOut = writer.toString(); assertTrue(dataOut.contains("Aws::String m_clientToken{Aws::Utils::UUID::PseudoRandomUUID()};"), "Excluding overload should also emit the idempotency-token initializer: " + dataOut); CppWriter flagWriter = new CppWriter(); - MemberRenderer.renderPrivateHasBeenSetFlagsExcluding(flagWriter, shape, model, "other"); + MemberRenderer.forStructure(model, shape, null).excluding("other").renderHasBeenSetFlags(flagWriter); String flagOut = flagWriter.toString(); assertTrue(flagOut.contains("bool m_clientTokenHasBeenSet = true;"), "Excluding overload should also emit HasBeenSet = true: " + flagOut); @@ -367,7 +367,7 @@ void renderPrivateSection_hasBeenSetFlagsGroupedAtEnd() { .build(); Model model = Model.builder().addShapes(str, intShape, shape).build(); CppWriter writer = new CppWriter(); - MemberRenderer.renderPrivateSection(writer, shape, model); + MemberRenderer.forStructure(model, shape, null).renderPrivateSection(writer); String output = writer.toString(); // HasBeenSet flags should come after data members int nameFieldPos = output.indexOf("Aws::String m_name;"); @@ -394,29 +394,4 @@ void renderRequestIdAccessors_emitsTemplatedGetSetWith() { assertTrue(out.contains("///@{")); assertTrue(out.contains("///@}")); } - - @Test - void render_withOptions_matchesRenderPublicSection() { - // Build the same shape twice and assert the options-object path equals the legacy path. - software.amazon.smithy.model.shapes.StringShape str = - software.amazon.smithy.model.shapes.StringShape.builder().id("com.example#String").build(); - software.amazon.smithy.model.shapes.StructureShape shape = - software.amazon.smithy.model.shapes.StructureShape.builder() - .id("com.example#Foo") - .addMember("ShardId", str.getId()) - .build(); - software.amazon.smithy.model.Model model = - software.amazon.smithy.model.Model.builder().addShapes(str, shape).build(); - - com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter legacy = - new com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter(); - MemberRenderer.renderPublicSection(legacy, shape, model, "AWS_EXAMPLE_API", "Foo"); - - com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter viaOpts = - new com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter(); - MemberRenderer.render(viaOpts, shape, model, - new MemberOptions().exportMacro("AWS_EXAMPLE_API").className("Foo").emitHasBeenSet(true)); - - assertEquals(legacy.toString(), viaOpts.toString()); - } } From 0a43d31fbca1c626ff11bee8b7822cbab2e18262 Mon Sep 17 00:00:00 2001 From: sbaluja Date: Thu, 13 Aug 2026 11:36:14 -0400 Subject: [PATCH 06/19] Revrt accidental crt update --- crt/aws-crt-cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crt/aws-crt-cpp b/crt/aws-crt-cpp index 2343b63d8be7..851d8d003c9d 160000 --- a/crt/aws-crt-cpp +++ b/crt/aws-crt-cpp @@ -1 +1 @@ -Subproject commit 2343b63d8be7cbe209918e032f6204c75cd9a84e +Subproject commit 851d8d003c9d5150edab56807e2393013f3771de From baac01e87c3e7781988fc26c0952cd44712e27bd Mon Sep 17 00:00:00 2001 From: sbaluja Date: Thu, 13 Aug 2026 12:59:50 -0400 Subject: [PATCH 07/19] Remove unused serde stub class --- .../generators/model/SerdeStub.java | 160 ------------------ .../generators/model/SerdeStubTest.java | 49 ------ 2 files changed, 209 deletions(-) delete mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SerdeStub.java delete mode 100644 tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SerdeStubTest.java diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SerdeStub.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SerdeStub.java deleted file mode 100644 index 0efd09b7dc20..000000000000 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SerdeStub.java +++ /dev/null @@ -1,160 +0,0 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -package com.amazonaws.util.awsclientsmithygenerator.generators.model; - -import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; -import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; -import software.amazon.smithy.model.Model; -import software.amazon.smithy.model.shapes.StructureShape; - -/** - * Generates protocol-specific serde method declarations (header) and empty stub - * implementations (source). The stubs will be replaced by schema-based serde. - */ -public final class SerdeStub { - - private SerdeStub() { - } - - public static void renderHeaderDeclarations(CppWriter writer, Protocol protocol, - String exportMacro, String className) { - renderHeaderDeclarations(writer, protocol, exportMacro, className, null); - } - - /** - * Emits the protocol-specific serde method declarations for a class. - * - * @param beforeSerializeMethod optional hook run after the (de)serialization constructor - * and {@code operator=} declarations but before the serialize method - * ({@code Jsonize}/{@code AddToNode}/{@code OutputToStream}). Used to inject - * additional constructors (e.g. the event-stream initial-response header ctor) - * at the mainline position. Ignored when {@code null}. - */ - public static void renderHeaderDeclarations(CppWriter writer, Protocol protocol, - String exportMacro, String className, - Runnable beforeSerializeMethod) { - if (protocol.isJsonLike()) { - writer.write("$L $L() = default;", exportMacro, className); - writer.write("$L $L(Aws::Utils::Json::JsonView jsonValue);", exportMacro, className); - writer.write("$L $L& operator=(Aws::Utils::Json::JsonView jsonValue);", exportMacro, className); - if (beforeSerializeMethod != null) { - beforeSerializeMethod.run(); - } - writer.write("$L Aws::Utils::Json::JsonValue Jsonize() const;", exportMacro); - } else if (protocol == Protocol.REST_XML) { - writer.write("$L $L() = default;", exportMacro, className); - writer.write("$L $L(const Aws::Utils::Xml::XmlNode& xmlNode);", exportMacro, className); - writer.write("$L $L& operator=(const Aws::Utils::Xml::XmlNode& xmlNode);", exportMacro, className); - if (beforeSerializeMethod != null) { - beforeSerializeMethod.run(); - } - writer.write("$L void AddToNode(Aws::Utils::Xml::XmlNode& parentNode) const;", exportMacro); - } else if (protocol == Protocol.QUERY_XML || protocol == Protocol.EC2) { - writer.write("$L $L() = default;", exportMacro, className); - writer.write("$L $L(const Aws::Utils::Xml::XmlNode& xmlNode);", exportMacro, className); - writer.write("$L $L& operator=(const Aws::Utils::Xml::XmlNode& xmlNode);", exportMacro, className); - if (beforeSerializeMethod != null) { - beforeSerializeMethod.run(); - } - writer.write("$L void OutputToStream(Aws::OStream& ostream, const char* location, unsigned index, const char* locationValue) const;", exportMacro); - writer.write("$L void OutputToStream(Aws::OStream& ostream, const char* location) const;", exportMacro); - } else { - throw new UnsupportedOperationException("Unsupported protocol for serde header declarations: " + protocol); - } - } - - public static void renderSourceImplementation(CppWriter writer, StructureShape shape, - Model model, Protocol protocol, - String className, String serviceName, - String projectName) { - if (protocol.isJsonLike()) { - renderJsonStub(writer, className); - } else if (protocol == Protocol.REST_XML) { - renderXmlStub(writer, className); - } else if (protocol == Protocol.QUERY_XML || protocol == Protocol.EC2) { - renderQueryXmlStub(writer, className); - } else { - throw new UnsupportedOperationException("Unsupported protocol for serde source implementation: " + protocol); - } - } - - /** - * Emits the empty per-protocol serde source bodies for a class that has no backing - * StructureShape (event stream union / initial response). Mirrors - * {@link #renderSourceImplementation} but keyed only on the class name. - */ - public static void renderSerdeSourceStub(CppWriter writer, Protocol protocol, String className) { - if (protocol.isJsonLike()) { - renderJsonStub(writer, className); - } else if (protocol == Protocol.REST_XML) { - renderXmlStub(writer, className); - } else if (protocol == Protocol.QUERY_XML || protocol == Protocol.EC2) { - renderQueryXmlStub(writer, className); - } else { - throw new UnsupportedOperationException("Unsupported protocol for serde source stub: " + protocol); - } - } - - /** - * Emits a protocol-agnostic stub for an event-stream event case body: a TODO marker - * and a minimal, compilable callback invocation with a default-constructed event. - * No protocol-specific deserialization is emitted. - * - * @param writer the CppWriter - * @param eventShapeName the C++ event shape type (e.g. "SubscribeToShardEvent") - * @param callbackMember the handler callback member (e.g. "m_onSubscribeToShardEvent") - */ - public static void renderEventPayloadDecodeStub(CppWriter writer, String eventShapeName, - String callbackMember) { - writer.write("// TODO: protocol-specific event payload deserialization"); - writer.write("$L($L{});", callbackMember, eventShapeName); - } - - /** - * Emits a protocol-agnostic stub in place of the protocol-specific error-payload parse. - * The header-derived error code/message still flow to MarshallError at the call site. - */ - public static void renderErrorPayloadParseStub(CppWriter writer) { - writer.write("// TODO: protocol-specific error payload deserialization"); - } - - private static void renderJsonStub(CppWriter writer, String className) { - writer.write("$L::$L(JsonView jsonValue) { *this = jsonValue; }", className, className); - writer.write(""); - writer.openBlock("$L& $L::operator=(JsonView jsonValue) {", "}", className, className, () -> { - writer.write("return *this;"); - }); - writer.write(""); - writer.openBlock("JsonValue $L::Jsonize() const {", "}", className, () -> { - writer.write("JsonValue payload;"); - writer.write("return payload;"); - }); - } - - private static void renderXmlStub(CppWriter writer, String className) { - writer.write("$L::$L(const XmlNode& xmlNode) { *this = xmlNode; }", className, className); - writer.write(""); - writer.openBlock("$L& $L::operator=(const XmlNode& xmlNode) {", "}", className, className, () -> { - writer.write("return *this;"); - }); - writer.write(""); - writer.openBlock("void $L::AddToNode(XmlNode& parentNode) const {", "}", className, () -> { - }); - } - - private static void renderQueryXmlStub(CppWriter writer, String className) { - writer.write("$L::$L(const XmlNode& xmlNode) { *this = xmlNode; }", className, className); - writer.write(""); - writer.openBlock("$L& $L::operator=(const XmlNode& xmlNode) {", "}", className, className, () -> { - writer.write("return *this;"); - }); - writer.write(""); - writer.openBlock("void $L::OutputToStream(Aws::OStream& ostream, const char* location, unsigned index, const char* locationValue) const {", "}", className, () -> { - }); - writer.write(""); - writer.openBlock("void $L::OutputToStream(Aws::OStream& ostream, const char* location) const {", "}", className, () -> { - }); - } -} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SerdeStubTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SerdeStubTest.java deleted file mode 100644 index 2335c427e3a8..000000000000 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/SerdeStubTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -package com.amazonaws.util.awsclientsmithygenerator.generators.model; - -import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; -import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -class SerdeStubTest { - - @Test - void renderEventPayloadDecodeStub_emitsTodoAndNoProtocolTokens() { - CppWriter writer = new CppWriter(); - SerdeStub.renderEventPayloadDecodeStub(writer, "SubscribeToShardEvent", "m_onSubscribeToShardEvent"); - String out = writer.toString(); - assertTrue(out.contains("// TODO: protocol-specific event payload deserialization"), - "Missing TODO marker: " + out); - assertTrue(out.contains("m_onSubscribeToShardEvent(SubscribeToShardEvent{});"), - "Missing callback invocation: " + out); - assertFalse(out.contains("JsonValue"), "Should not emit JSON tokens: " + out); - assertFalse(out.contains("Cbor"), "Should not emit CBOR tokens: " + out); - } - - @Test - void renderErrorPayloadParseStub_emitsTodoOnly() { - CppWriter writer = new CppWriter(); - SerdeStub.renderErrorPayloadParseStub(writer); - String out = writer.toString(); - assertTrue(out.contains("// TODO: protocol-specific error payload deserialization"), - "Missing TODO marker: " + out); - assertFalse(out.contains("JsonView"), "Should not emit JSON tokens: " + out); - } - - @Test - void renderSerdeSourceStub_json_emitsEmptyBodies() { - CppWriter writer = new CppWriter(); - SerdeStub.renderSerdeSourceStub(writer, Protocol.JSON, "SubscribeToShardEventStream"); - String out = writer.toString(); - assertTrue(out.contains("SubscribeToShardEventStream::SubscribeToShardEventStream(JsonView jsonValue)"), - "Missing JSON ctor stub: " + out); - assertTrue(out.contains("JsonValue SubscribeToShardEventStream::Jsonize() const"), - "Missing Jsonize stub: " + out); - } -} From 2c4496df47395ffb21fec25f44d0dfc085c7ee83 Mon Sep 17 00:00:00 2001 From: sbaluja Date: Thu, 13 Aug 2026 13:38:54 -0400 Subject: [PATCH 08/19] Fix request specific headers generation bug --- .../model/renderers/RequestRenderer.java | 45 ++++++++----- .../generators/model/RequestRendererTest.java | 63 +++++++++++++++++++ 2 files changed, 94 insertions(+), 14 deletions(-) diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java index 515c7bd1ad7e..1bf02659ee90 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java @@ -69,18 +69,7 @@ private void renderHeader(CppWriterDelegator writerDelegator, Optional eventStreamMember = ShapeClassifier.eventStreamMemberName(rawShape, ctx.model()); StructureShape includeShape = rawStreamingPayload ? shapeExcluding(rawShape, Set.of("contentType", "ContentType")) : rawShape; - Set genericExcluded = new HashSet<>(); - if (rawStreamingPayload) { - // isRawStreamingPayloadRequest guarantees a payload member; absence is a codegen bug. - String payloadMember = ShapeClassifier.rawStreamingPayloadMemberName(rawShape, ctx.model()) - .orElseThrow(() -> new IllegalStateException( - "Raw streaming payload request without a payload member: " + rawShape.getId())); - genericExcluded.add("contentType"); - genericExcluded.add("ContentType"); - genericExcluded.add(payloadMember); - } - eventStreamMember.ifPresent(genericExcluded::add); - StructureShape shape = genericExcluded.isEmpty() ? rawShape : shapeExcluding(rawShape, genericExcluded); + StructureShape shape = renderedShape(rawShape, operation); String fileName = "include/aws/" + ctx.smithyServiceName() + "/model/" + className + ".h"; writerDelegator.useFileWriter(fileName, writer -> { writer.write("#pragma once"); @@ -227,9 +216,14 @@ private void renderHeader(CppWriterDelegator writerDelegator, } private void renderSource(CppWriterDelegator writerDelegator, - StructureShape shape, OperationShape operation) { + StructureShape rawShape, OperationShape operation) { String className = operation.getId().getName() + "Request"; - Optional eventStreamMember = ShapeClassifier.eventStreamMemberName(shape, ctx.model()); + Optional eventStreamMember = ShapeClassifier.eventStreamMemberName(rawShape, ctx.model()); + // Render request-method impls from the same member-stripped shape as the header (see + // renderedShape): the declaration and definition gate GetRequestSpecificHeaders / + // AddQueryStringParameters on this shape, so they must agree or the source emits an + // out-of-line definition of a method the class never declares. + StructureShape shape = renderedShape(rawShape, operation); String fileName = "source/model/" + className + ".cpp"; writerDelegator.useFileWriter(fileName, writer -> { @@ -292,6 +286,29 @@ private void renderSource(CppWriterDelegator writerDelegator, }); } + /** + * The shape whose members drive request-method rendering. Raw-streaming-payload requests strip + * {@code contentType} (supplied by the streaming base's GetContentType/SetContentType) and the + * {@code @httpPayload} member (sent via the body stream); an event-stream input member is + * rendered separately, not through the generic member path. Both the header (declarations) and + * the source (definitions) MUST render from this same shape so their emitted method sets stay + * in sync. + */ + private StructureShape renderedShape(StructureShape rawShape, OperationShape operation) { + Set excluded = new HashSet<>(); + if (ShapeClassifier.isRawStreamingPayloadRequest(operation, ctx.model())) { + // isRawStreamingPayloadRequest guarantees a payload member; absence is a codegen bug. + String payloadMember = ShapeClassifier.rawStreamingPayloadMemberName(rawShape, ctx.model()) + .orElseThrow(() -> new IllegalStateException( + "Raw streaming payload request without a payload member: " + rawShape.getId())); + excluded.add("contentType"); + excluded.add("ContentType"); + excluded.add(payloadMember); + } + ShapeClassifier.eventStreamMemberName(rawShape, ctx.model()).ifPresent(excluded::add); + return excluded.isEmpty() ? rawShape : shapeExcluding(rawShape, excluded); + } + /** Builds a copy of {@code shape} with the named members removed (null names are ignored). */ private StructureShape shapeExcluding(StructureShape shape, Set excluded) { StructureShape.Builder builder = StructureShape.builder().id(shape.getId()); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RequestRendererTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RequestRendererTest.java index 0d204db610ed..86b992ece52d 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RequestRendererTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RequestRendererTest.java @@ -303,4 +303,67 @@ void rawStreamingPayloadRequestSource_usesStreamIncludesNotJsonSerde() { assertFalse(c.contains("using namespace Aws::Utils::Json;"), "Streaming-payload request source must not use the Json namespace: " + c); } + + /** + * Same as {@link #rawStreamingPayloadRequestModel()} but under REST-JSON, where {@code contentType} + * (stripped, supplied by the streaming base) is the ONLY header-bound member and + * {@code hasTargetHeader()} is false. This is the combination that exposes header/source drift. + */ + private static Model rawStreamingPayloadRestJsonRequestModel() { + StringShape str = StringShape.builder().id("com.example#String").build(); + software.amazon.smithy.model.shapes.BlobShape blob = + software.amazon.smithy.model.shapes.BlobShape.builder().id("com.example#Body").build(); + StructureShape input = StructureShape.builder() + .id("com.example#DoStreamInput") + .addMember(MemberShape.builder() + .id("com.example#DoStreamInput$body").target(blob.getId()) + .addTrait(new software.amazon.smithy.model.traits.HttpPayloadTrait()).build()) + .addMember(MemberShape.builder() + .id("com.example#DoStreamInput$contentType").target(str.getId()) + .addTrait(new software.amazon.smithy.model.traits.HttpHeaderTrait("Content-Type")).build()) + .addMember("modelId", str.getId()) + .build(); + StructureShape output = StructureShape.builder() + .id("com.example#DoStreamOutput").addMember("r", str.getId()).build(); + OperationShape op = OperationShape.builder() + .id("com.example#DoStream").input(input.getId()).output(output.getId()) + .addTrait(software.amazon.smithy.aws.traits.protocols.RestJson1Trait.builder().build()) + .build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#Example").version("2024-01-01") + .addTrait(software.amazon.smithy.aws.traits.protocols.RestJson1Trait.builder().build()) + .addOperation(op.getId()).build(); + return Model.builder().addShapes(str, blob, input, output, op, service).build(); + } + + private static String renderRawStreamingPayloadRestJsonRequest(String fileSuffix) { + Model model = rawStreamingPayloadRestJsonRequestModel(); + ServiceShape service = model.expectShape(ShapeId.from("com.example#Example"), ServiceShape.class); + MockManifest manifest = new MockManifest(); + CppWriterDelegator delegator = new CppWriterDelegator(manifest); + Protocol protocol = ProtocolResolver.resolve(service, model); + new RequestRenderer( + ShapeClassifier.classify(model, service, protocol).requests(), + new RenderContext(model, service, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example")).render(delegator); + delegator.flushWriters(); + return manifest.getFileString(manifest.getFiles().stream() + .filter(p -> p.toString().endsWith(fileSuffix)).findFirst().orElseThrow()).orElseThrow(); + } + + @Test + void rawStreamingPayloadRequestRestJson_headerAndSourceAgreeOnRequestSpecificHeaders() { + // Under a REST protocol (hasTargetHeader() == false), a raw-streaming-payload request whose + // ONLY header-bound member is the stripped contentType must emit GetRequestSpecificHeaders in + // NEITHER the header nor the source. The header renders from the contentType-excluded shape; + // the source MUST render from the same shape. Otherwise the source defines + // GetRequestSpecificHeaders() out-of-line for a method the header never declares (a C++ + // compile error). + String h = renderRawStreamingPayloadRestJsonRequest("DoStreamRequest.h"); + String c = renderRawStreamingPayloadRestJsonRequest("DoStreamRequest.cpp"); + assertFalse(h.contains("GetRequestSpecificHeaders"), + "Header must not declare GetRequestSpecificHeaders (contentType is stripped): " + h); + assertFalse(c.contains("GetRequestSpecificHeaders"), + "Source must not define GetRequestSpecificHeaders (contentType is stripped): " + c); + } } From 3851e7d3dbb38dc7c6ccf7d4d7fe523df7220706 Mon Sep 17 00:00:00 2001 From: sbaluja Date: Thu, 13 Aug 2026 14:05:57 -0400 Subject: [PATCH 09/19] Add proper list imports, avoid if/continue loops --- .../generators/model/MemberRenderer.java | 5 ++--- .../model/protocol/CborProtocolTraits.java | 16 ++++++++------ .../model/protocol/JsonProtocolTraits.java | 14 +++++++----- .../model/protocol/ProtocolTraits.java | 6 +++-- .../protocol/QueryXmlProtocolTraits.java | 22 ++++++++++--------- .../model/protocol/RestXmlProtocolTraits.java | 14 +++++++----- .../model/renderers/EventStreamRenderer.java | 8 +++---- 7 files changed, 47 insertions(+), 38 deletions(-) diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java index 71d5156b1ed8..1af17c84f7f3 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java @@ -193,10 +193,9 @@ public void renderDataMembers(CppWriter writer) { /** Private {@code HasBeenSet} flags (one per member, no blank lines), skipping the excluded member. */ public void renderHasBeenSetFlags(CppWriter writer) { for (Map.Entry entry : shape.getAllMembers().entrySet()) { - if (entry.getKey().equals(exclude)) { - continue; + if (!entry.getKey().equals(exclude)) { + writeHasBeenSetFlag(writer, entry.getValue(), entry.getKey()); } - writeHasBeenSetFlag(writer, entry.getValue(), entry.getKey()); } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraits.java index 05d204540187..8baef186b522 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/CborProtocolTraits.java @@ -12,6 +12,8 @@ import software.amazon.smithy.model.shapes.StructureShape; import software.amazon.smithy.model.traits.UnitTypeTrait; +import java.util.List; + /** * CBOR (Smithy {@code rpcv2Cbor}) serde rendering. Distinct from the JSON family: it * uses {@code Aws::Utils::Cbor::CborValue} model/result types, includes the CRT and core @@ -77,13 +79,13 @@ public void writeResultSerdeDecls(CppWriter writer, String exportMacro, String c } @Override - public java.util.List serdeIncludes(FileKind kind) { + public List serdeIncludes(FileKind kind) { switch (kind) { // CborSubObjectHeader.vm / CborResultHeader.vm hard-include : the // header signatures reference Aws::Crt::Cbor::CborDecoder / CborEncoder directly. case SUBOBJECT_HEADER: case RESULT_HEADER: - return java.util.List.of("aws/crt/cbor/Cbor.h"); + return List.of("aws/crt/cbor/Cbor.h"); // All source kinds share one union (supersets allowed). Usings are unchanged. case SUBOBJECT_SOURCE: case REQUEST_SOURCE: @@ -91,7 +93,7 @@ public java.util.List serdeIncludes(FileKind kind) { case STREAMING_RESULT_SOURCE: case EVENT_HANDLER_SOURCE: case INITIAL_RESPONSE_SOURCE: - return java.util.List.of( + return List.of( "aws/crt/cbor/Cbor.h", "aws/core/utils/cbor/CborValue.h", "aws/core/utils/UnreferencedParam.h", @@ -105,19 +107,19 @@ public java.util.List serdeIncludes(FileKind kind) { } @Override - public java.util.List serdeUsings(FileKind kind) { + public List serdeUsings(FileKind kind) { switch (kind) { case EVENT_HANDLER_SOURCE: - return java.util.List.of(serdeNamespace()); + return List.of(serdeNamespace()); case RESULT_SOURCE: case INITIAL_RESPONSE_SOURCE: // CborResultSource.vm pulls the full set (result payloads use the CborValue DOM). - return java.util.List.of("Aws::Crt", "Aws::Crt::Cbor", "Aws::Utils", "Aws::Utils::Cbor"); + return List.of("Aws::Crt", "Aws::Crt::Cbor", "Aws::Utils", "Aws::Utils::Cbor"); case REQUEST_SOURCE: case SUBOBJECT_SOURCE: // CborRequestSource.vm / CborSubObjectSource.vm: streaming encode/decode only — // just Aws::Crt::Cbor + Aws::Utils, no Aws::Crt / Aws::Utils::Cbor. - return java.util.List.of("Aws::Crt::Cbor", "Aws::Utils"); + return List.of("Aws::Crt::Cbor", "Aws::Utils"); default: throw new UnsupportedOperationException( "No serde usings defined for FileKind " + kind + " in CborProtocolTraits"); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraits.java index f3ebf854a985..9996841ba713 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/JsonProtocolTraits.java @@ -11,6 +11,8 @@ import software.amazon.smithy.model.shapes.ServiceShape; import software.amazon.smithy.model.shapes.StructureShape; +import java.util.List; + /** * JSON-flavored serde rendering. Serves {@link Protocol#JSON} (awsJson-RPC) and * {@link Protocol#REST_JSON} (rest-json), which share an identical C++ serde surface and @@ -80,12 +82,12 @@ public void writeResultSerdeDecls(CppWriter writer, String exportMacro, String c } @Override - public java.util.List serdeIncludes(FileKind kind) { + public List serdeIncludes(FileKind kind) { switch (kind) { // Headers forward-declare JsonValue/JsonView; no serializer include. case SUBOBJECT_HEADER: case RESULT_HEADER: - return java.util.List.of(); + return List.of(); // All source kinds share one union (supersets allowed: a .cpp may carry an // include it doesn't strictly use). Usings are unchanged; only #includes widen. case SUBOBJECT_SOURCE: @@ -94,7 +96,7 @@ public java.util.List serdeIncludes(FileKind kind) { case STREAMING_RESULT_SOURCE: case EVENT_HANDLER_SOURCE: case INITIAL_RESPONSE_SOURCE: - return java.util.List.of( + return List.of( "aws/core/utils/json/JsonSerializer.h", "aws/core/utils/UnreferencedParam.h", "aws/core/utils/memory/stl/AWSStringStream.h", @@ -107,15 +109,15 @@ public java.util.List serdeIncludes(FileKind kind) { } @Override - public java.util.List serdeUsings(FileKind kind) { + public List serdeUsings(FileKind kind) { switch (kind) { case EVENT_HANDLER_SOURCE: - return java.util.List.of(serdeNamespace()); + return List.of(serdeNamespace()); case RESULT_SOURCE: case INITIAL_RESPONSE_SOURCE: case REQUEST_SOURCE: case SUBOBJECT_SOURCE: - return java.util.List.of("Aws::Utils::Json", "Aws::Utils"); + return List.of("Aws::Utils::Json", "Aws::Utils"); default: throw new UnsupportedOperationException( "No serde usings defined for FileKind " + kind + " in JsonProtocolTraits"); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraits.java index 761648644314..d7002148dc06 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/ProtocolTraits.java @@ -13,6 +13,8 @@ import software.amazon.smithy.model.shapes.ServiceShape; import software.amazon.smithy.model.shapes.StructureShape; +import java.util.List; + /** * Owns every protocol-specific rendering decision for generated model code. * @@ -37,10 +39,10 @@ public interface ProtocolTraits { // ------------------------------------------------------------------ /** Protocol-specific serde {@code #include} paths (no angle brackets) for the given file kind. */ - java.util.List serdeIncludes(FileKind kind); + List serdeIncludes(FileKind kind); /** {@code using namespace} targets for the given file kind. */ - java.util.List serdeUsings(FileKind kind); + List serdeUsings(FileKind kind); // ------------------------------------------------------------------ // Header side diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/QueryXmlProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/QueryXmlProtocolTraits.java index 7fa938f81486..b4409b578cac 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/QueryXmlProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/QueryXmlProtocolTraits.java @@ -11,6 +11,8 @@ import software.amazon.smithy.model.shapes.ServiceShape; import software.amazon.smithy.model.shapes.StructureShape; +import java.util.List; + /** * Query-XML serde rendering. Serves both {@link Protocol#QUERY_XML} and * {@link Protocol#EC2}: shapes serialize into a flat, indexed query string via two @@ -86,13 +88,13 @@ public void writeResultSerdeDecls(CppWriter writer, String exportMacro, String c } @Override - public java.util.List serdeIncludes(FileKind kind) { + public List serdeIncludes(FileKind kind) { switch (kind) { case SUBOBJECT_HEADER: - return java.util.List.of("aws/core/utils/memory/stl/AWSStreamFwd.h"); + return List.of("aws/core/utils/memory/stl/AWSStreamFwd.h"); case RESULT_HEADER: // Query/EC2 result headers forward-declare XmlDocument; no serde include. - return java.util.List.of(); + return List.of(); case SUBOBJECT_SOURCE: case REQUEST_SOURCE: case RESULT_SOURCE: @@ -101,7 +103,7 @@ public java.util.List serdeIncludes(FileKind kind) { case INITIAL_RESPONSE_SOURCE: // All source kinds share one union (supersets allowed). Usings are unchanged. // No Query source arm carried , so the union omits it. - return java.util.List.of( + return List.of( "aws/core/utils/xml/XmlSerializer.h", "aws/core/utils/logging/LogMacros.h", "aws/core/utils/UnreferencedParam.h", @@ -115,18 +117,18 @@ public java.util.List serdeIncludes(FileKind kind) { } @Override - public java.util.List serdeUsings(FileKind kind) { + public List serdeUsings(FileKind kind) { switch (kind) { case RESULT_SOURCE: - return java.util.List.of("Aws::Utils::Xml", "Aws::Utils::Logging", "Aws::Utils"); + return List.of("Aws::Utils::Xml", "Aws::Utils::Logging", "Aws::Utils"); case INITIAL_RESPONSE_SOURCE: - return java.util.List.of("Aws::Utils::Xml", "Aws::Utils"); + return List.of("Aws::Utils::Xml", "Aws::Utils"); case REQUEST_SOURCE: - return java.util.List.of("Aws::Utils"); + return List.of("Aws::Utils"); case EVENT_HANDLER_SOURCE: - return java.util.List.of(serdeNamespace()); + return List.of(serdeNamespace()); case SUBOBJECT_SOURCE: - return java.util.List.of("Aws::Utils::Xml", "Aws::Utils"); + return List.of("Aws::Utils::Xml", "Aws::Utils"); default: throw new UnsupportedOperationException( "No serde usings defined for FileKind " + kind + " in QueryXmlProtocolTraits"); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RestXmlProtocolTraits.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RestXmlProtocolTraits.java index c4da525e0b3f..4eda33f32fde 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RestXmlProtocolTraits.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/protocol/RestXmlProtocolTraits.java @@ -11,6 +11,8 @@ import software.amazon.smithy.model.shapes.ServiceShape; import software.amazon.smithy.model.shapes.StructureShape; +import java.util.List; + /** * REST-XML serde rendering. Shapes serialize by attaching themselves to a parent * node via {@code AddToNode}. @@ -66,12 +68,12 @@ public void writeResultSerdeDecls(CppWriter writer, String exportMacro, String c } @Override - public java.util.List serdeIncludes(FileKind kind) { + public List serdeIncludes(FileKind kind) { switch (kind) { // Sub-object and result headers forward-declare XmlNode/XmlDocument; no serializer include. case SUBOBJECT_HEADER: case RESULT_HEADER: - return java.util.List.of(); + return List.of(); // All source kinds share one union (supersets allowed). Usings are unchanged. case SUBOBJECT_SOURCE: case REQUEST_SOURCE: @@ -79,7 +81,7 @@ public java.util.List serdeIncludes(FileKind kind) { case STREAMING_RESULT_SOURCE: case EVENT_HANDLER_SOURCE: case INITIAL_RESPONSE_SOURCE: - return java.util.List.of( + return List.of( "aws/core/utils/xml/XmlSerializer.h", "aws/core/utils/memory/stl/AWSStringStream.h", "aws/core/utils/UnreferencedParam.h", @@ -92,15 +94,15 @@ public java.util.List serdeIncludes(FileKind kind) { } @Override - public java.util.List serdeUsings(FileKind kind) { + public List serdeUsings(FileKind kind) { switch (kind) { case EVENT_HANDLER_SOURCE: - return java.util.List.of(serdeNamespace()); + return List.of(serdeNamespace()); case RESULT_SOURCE: case INITIAL_RESPONSE_SOURCE: case REQUEST_SOURCE: case SUBOBJECT_SOURCE: - return java.util.List.of("Aws::Utils::Xml", "Aws::Utils"); + return List.of("Aws::Utils::Xml", "Aws::Utils"); default: throw new UnsupportedOperationException( "No serde usings defined for FileKind " + kind + " in RestXmlProtocolTraits"); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EventStreamRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EventStreamRenderer.java index 83420c3f6b42..f256588f006c 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EventStreamRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/EventStreamRenderer.java @@ -420,11 +420,11 @@ private StructureShape initialResponseShape(String opName, StructureShape result .id("com.amazonaws.smithy.synthetic#" + opName + "InitialResponse"); for (MemberShape member : resultShape.getAllMembers().values()) { Shape target = ctx.model().expectShape(member.getTarget()); - if (target.isUnionShape() && target.hasTrait(StreamingTrait.class)) { - continue; + boolean isEventStream = target.isUnionShape() && target.hasTrait(StreamingTrait.class); + if (!isEventStream) { + builder.addMember(member.getMemberName(), member.getTarget(), + b -> member.getAllTraits().values().forEach(b::addTrait)); } - builder.addMember(member.getMemberName(), member.getTarget(), - b -> member.getAllTraits().values().forEach(b::addTrait)); } return builder.build(); } From 1afb8552d84db83863b894eb73f5c6189ae479a2 Mon Sep 17 00:00:00 2001 From: sbaluja Date: Thu, 13 Aug 2026 14:54:18 -0400 Subject: [PATCH 10/19] Sparse trait handling --- .../generators/model/CppTypeMapper.java | 27 +++++- .../generators/model/MemberRenderer.java | 26 +++++- .../generators/model/CppTypeMapperTest.java | 87 +++++++++++++++++++ .../model/MemberRendererOutputTest.java | 57 ++++++++++++ 4 files changed, 194 insertions(+), 3 deletions(-) diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java index 20f86fa28e7f..8f8a0fb67f56 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java @@ -11,6 +11,7 @@ import software.amazon.smithy.model.shapes.Shape; import software.amazon.smithy.model.traits.IdempotencyTokenTrait; import software.amazon.smithy.model.traits.SensitiveTrait; +import software.amazon.smithy.model.traits.SparseTrait; import java.util.ArrayList; import java.util.List; @@ -106,14 +107,17 @@ public static String getCppType(Shape shape, Model model, boolean wideIntegers) if (shape.isListShape()) { ListShape list = shape.asListShape().get(); Shape member = model.expectShape(list.getMember().getTarget()); - return "Aws::Vector<" + getCppType(member, model, wideIntegers) + ">"; + // A @sparse list wraps its element type in Aws::Crt::Optional (matches C2J's + // CppViewHelper), giving Aws::Vector>. + return "Aws::Vector<" + wrapSparse(shape, getCppType(member, model, wideIntegers)) + ">"; } if (shape.isMapShape()) { MapShape map = shape.asMapShape().get(); Shape key = model.expectShape(map.getKey().getTarget()); Shape value = model.expectShape(map.getValue().getTarget()); + // A @sparse map wraps its value type (not its key) in Aws::Crt::Optional. return "Aws::Map<" + getCppType(key, model, wideIntegers) + ", " - + getCppType(value, model, wideIntegers) + ">"; + + wrapSparse(shape, getCppType(value, model, wideIntegers)) + ">"; } if (shape.isDocumentShape()) { return "Aws::Utils::Document"; @@ -122,6 +126,20 @@ public static String getCppType(Shape shape, Model model, boolean wideIntegers) "Unsupported shape type " + shape.getType() + " for shape " + shape.getId()); } + /** + * Wraps {@code innerType} in {@code Aws::Crt::Optional<...>} when {@code collectionShape} + * (a list or map) carries the {@code @sparse} trait; otherwise returns {@code innerType} + * unchanged. For lists the inner type is the element; for maps it is the value. + * + * @param collectionShape the list or map shape that may be sparse + * @param innerType the element / value C++ type + * @return the (possibly Optional-wrapped) type + */ + public static String wrapSparse(Shape collectionShape, String innerType) { + return collectionShape.hasTrait(SparseTrait.class) + ? "Aws::Crt::Optional<" + innerType + ">" : innerType; + } + /** * Returns the C++ default initializer for a shape that needs one, or empty * if the type is default-constructed (strings, vectors, maps, etc.). @@ -243,6 +261,11 @@ public static List getIncludesForShape(Shape structureShape, Model model getIncludeForMemberType(key, model, projectName).ifPresent(includes::add); getIncludeForMemberType(value, model, projectName).ifPresent(includes::add); } + // A @sparse list/map wraps its element/value in Aws::Crt::Optional, declared in + // . Matches C2J's generated SparseNullsOperationRequest.h. + if ((target.isListShape() || target.isMapShape()) && target.hasTrait(SparseTrait.class)) { + includes.add(""); + } // @idempotencyToken members are brace-initialized with // Aws::Utils::UUID::PseudoRandomUUID(), which requires UUID.h. Matches C2J // (CppViewHelper.computeMemberIncludeName). diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java index 1af17c84f7f3..2122f717e1a5 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java @@ -13,6 +13,7 @@ import software.amazon.smithy.model.shapes.Shape; import software.amazon.smithy.model.traits.DocumentationTrait; import software.amazon.smithy.model.traits.IdempotencyTokenTrait; +import software.amazon.smithy.model.traits.SparseTrait; import java.util.Map; @@ -123,6 +124,7 @@ public void renderPublicAccessors(CppWriter writer) { }); if (targetShape.isListShape()) { + boolean sparse = targetShape.hasTrait(SparseTrait.class); Shape elementShape = model.expectShape( targetShape.asListShape().get().getMember().getTarget()); String elementType = CppTypeMapper.getCppType(elementShape, model, wideIntegers); @@ -140,9 +142,19 @@ public void renderPublicAccessors(CppWriter writer) { writer.write("return *this;"); }); } + // A @sparse list also accepts the Optional element directly (matches C2J). + if (sparse) { + writer.openBlock("inline $L& Add$L(Aws::Crt::Optional<$L> value) {", "}", + className, methodName, elementType, () -> { + writer.write("$LHasBeenSet = true;", fieldName); + writer.write("$L.push_back(value);", fieldName); + writer.write("return *this;"); + }); + } } if (targetShape.isMapShape()) { + boolean sparse = targetShape.hasTrait(SparseTrait.class); Shape keyShape = model.expectShape( targetShape.asMapShape().get().getKey().getTarget()); Shape valueShape = model.expectShape( @@ -153,7 +165,10 @@ public void renderPublicAccessors(CppWriter writer) { if (bothForwardable) { String keyParam = methodName + "KeyT"; String valueParam = methodName + "ValueT"; - writer.write("template ", keyParam, keyType, valueParam, valueType); + // A @sparse map's forwarding Add defaults its value template to the wrapped + // Optional type (matches C2J); the key is untouched. + String valueParamDefault = sparse ? "Aws::Crt::Optional<" + valueType + ">" : valueType; + writer.write("template ", keyParam, keyType, valueParam, valueParamDefault); writer.openBlock("$L& Add$L($L&& key, $L&& value) {", "}", className, methodName, keyParam, valueParam, () -> { writer.write("$LHasBeenSet = true;", fieldName); writer.write("$L.emplace(std::forward<$L>(key), std::forward<$L>(value));", fieldName, keyParam, valueParam); @@ -166,6 +181,15 @@ public void renderPublicAccessors(CppWriter writer) { writer.write("return *this;"); }); } + // A @sparse map also accepts the raw key and the Optional value directly. + if (sparse) { + writer.openBlock("inline $L& Add$L($L key, Aws::Crt::Optional<$L> value) {", "}", + className, methodName, keyType, valueType, () -> { + writer.write("$LHasBeenSet = true;", fieldName); + writer.write("$L.emplace(key, value);", fieldName); + writer.write("return *this;"); + }); + } } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapperTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapperTest.java index cf41e3277fd7..8bcb29075f17 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapperTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapperTest.java @@ -134,6 +134,93 @@ void mapOfStringToString_mapsToAwsMap() { assertEquals("Aws::Map", CppTypeMapper.getCppType(map, model)); } + @Test + void sparseListOfStrings_wrapsElementInOptional() { + // C2J wraps a @sparse list's element type in Aws::Crt::Optional (CppViewHelper), so the + // member type becomes Aws::Vector>. + StringShape str = StringShape.builder().id("com.example#Str").build(); + ListShape list = ListShape.builder() + .id("com.example#SparseStringList") + .member(MemberShape.builder().id("com.example#SparseStringList$member").target("com.example#Str").build()) + .addTrait(new software.amazon.smithy.model.traits.SparseTrait()) + .build(); + Model model = Model.builder().addShapes(str, list).build(); + assertEquals("Aws::Vector>", CppTypeMapper.getCppType(list, model)); + } + + @Test + void sparseMapOfStringToString_wrapsValueInOptional() { + // C2J wraps a @sparse map's value type in Aws::Crt::Optional; the key is untouched. + StringShape str = StringShape.builder().id("com.example#Str").build(); + MapShape map = MapShape.builder() + .id("com.example#SparseStringMap") + .key(MemberShape.builder().id("com.example#SparseStringMap$key").target("com.example#Str").build()) + .value(MemberShape.builder().id("com.example#SparseStringMap$value").target("com.example#Str").build()) + .addTrait(new software.amazon.smithy.model.traits.SparseTrait()) + .build(); + Model model = Model.builder().addShapes(str, map).build(); + assertEquals("Aws::Map>", CppTypeMapper.getCppType(map, model)); + } + + @Test + void getIncludesForShape_withSparseListMember_includesOptionalHeader() { + // A @sparse list/map member wraps its element/value in Aws::Crt::Optional, which lives in + // . Matches C2J's generated SparseNullsOperationRequest.h. + StringShape str = StringShape.builder().id("com.example#Str").build(); + ListShape list = ListShape.builder() + .id("com.example#SparseStringList") + .member(MemberShape.builder().id("com.example#SparseStringList$member").target("com.example#Str").build()) + .addTrait(new software.amazon.smithy.model.traits.SparseTrait()) + .build(); + StructureShape struct = StructureShape.builder() + .id("com.example#MyRequest") + .addMember("items", list.getId()) + .build(); + Model model = Model.builder().addShapes(str, list, struct).build(); + + List includes = CppTypeMapper.getIncludesForShape(struct, model, "myservice"); + assertTrue(includes.contains(""), + "Shape with sparse list member should include Optional.h: " + includes); + } + + @Test + void getIncludesForShape_withSparseMapMember_includesOptionalHeader() { + StringShape str = StringShape.builder().id("com.example#Str").build(); + MapShape map = MapShape.builder() + .id("com.example#SparseStringMap") + .key(MemberShape.builder().id("com.example#SparseStringMap$key").target("com.example#Str").build()) + .value(MemberShape.builder().id("com.example#SparseStringMap$value").target("com.example#Str").build()) + .addTrait(new software.amazon.smithy.model.traits.SparseTrait()) + .build(); + StructureShape struct = StructureShape.builder() + .id("com.example#MyRequest") + .addMember("data", map.getId()) + .build(); + Model model = Model.builder().addShapes(str, map, struct).build(); + + List includes = CppTypeMapper.getIncludesForShape(struct, model, "myservice"); + assertTrue(includes.contains(""), + "Shape with sparse map member should include Optional.h: " + includes); + } + + @Test + void getIncludesForShape_withoutSparse_noOptionalHeader() { + StringShape str = StringShape.builder().id("com.example#Str").build(); + ListShape list = ListShape.builder() + .id("com.example#StringList") + .member(MemberShape.builder().id("com.example#StringList$member").target("com.example#Str").build()) + .build(); + StructureShape struct = StructureShape.builder() + .id("com.example#MyRequest") + .addMember("items", list.getId()) + .build(); + Model model = Model.builder().addShapes(str, list, struct).build(); + + List includes = CppTypeMapper.getIncludesForShape(struct, model, "myservice"); + assertFalse(includes.contains(""), + "Non-sparse list member should not include Optional.h: " + includes); + } + @Test void structureShape_mapsToShapeName() { StructureShape struct = StructureShape.builder().id("com.example#MyStruct").build(); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererOutputTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererOutputTest.java index 1bfad50e3ec6..ab92946cd6db 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererOutputTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererOutputTest.java @@ -72,4 +72,61 @@ void fullOutput_matchesExpectedPattern() { assertTrue(privOutput.contains("bool m_parentShardsHasBeenSet = false;")); assertTrue(privOutput.contains("bool m_hashKeyRangeHasBeenSet = false;")); } + + @Test + void sparseListAndMap_emitOptionalTypesAndAddOverloads() { + // Mirrors C2J's generated SparseNullsOperationRequest.h: a @sparse list/map wraps its + // element/value in Aws::Crt::Optional, and gets an extra Add overload accepting the + // Optional element/value directly. + StringShape str = StringShape.builder().id("com.example#String").build(); + ListShape sparseList = ListShape.builder() + .id("com.example#SparseStringList") + .member(MemberShape.builder().id("com.example#SparseStringList$member").target("com.example#String").build()) + .addTrait(new software.amazon.smithy.model.traits.SparseTrait()) + .build(); + MapShape sparseMap = MapShape.builder() + .id("com.example#SparseStringMap") + .key(MemberShape.builder().id("com.example#SparseStringMap$key").target("com.example#String").build()) + .value(MemberShape.builder().id("com.example#SparseStringMap$value").target("com.example#String").build()) + .addTrait(new software.amazon.smithy.model.traits.SparseTrait()) + .build(); + StructureShape shape = StructureShape.builder() + .id("com.example#SparseNullsOperationRequest") + .addMember("SparseStringList", sparseList.getId()) + .addMember("SparseStringMap", sparseMap.getId()) + .build(); + Model model = Model.builder().addShapes(str, sparseList, sparseMap, shape).build(); + + CppWriter writer = new CppWriter(); + MemberRenderer.forStructure(model, shape, "SparseNullsOperationRequest").renderPublicAccessors(writer); + String out = writer.toString(); + System.out.println(out); + + // --- sparse list --- + assertTrue(out.contains( + "inline const Aws::Vector>& GetSparseStringList() const { return m_sparseStringList; }"), + out); + // main forwarding Add keeps the UNWRAPPED element type as its template default (matches C2J) + assertTrue(out.contains("template "), out); + assertTrue(out.contains("m_sparseStringList.emplace_back(std::forward(value));"), out); + // extra overload takes the Optional element by value and push_backs it + assertTrue(out.contains( + "inline SparseNullsOperationRequest& AddSparseStringList(Aws::Crt::Optional value) {"), + out); + assertTrue(out.contains("m_sparseStringList.push_back(value);"), out); + + // --- sparse map --- + assertTrue(out.contains( + "inline const Aws::Map>& GetSparseStringMap() const { return m_sparseStringMap; }"), + out); + // templated Add value default IS the wrapped Optional type for maps (matches C2J) + assertTrue(out.contains( + "template >"), + out); + // extra overload takes the raw key and the Optional value + assertTrue(out.contains( + "inline SparseNullsOperationRequest& AddSparseStringMap(Aws::String key, Aws::Crt::Optional value) {"), + out); + assertTrue(out.contains("m_sparseStringMap.emplace(key, value);"), out); + } } From 1df8151f20a609e87005e893182be0fb265adbc6 Mon Sep 17 00:00:00 2001 From: sbaluja Date: Thu, 13 Aug 2026 16:10:04 -0400 Subject: [PATCH 11/19] Smithy enum 1.0 fix --- .../generators/model/CppTypeMapper.java | 24 +++++++++++++++---- .../generators/model/MemberRenderer.java | 6 ++--- .../generators/model/CppTypeMapperTest.java | 19 +++++++++++++++ 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java index 8f8a0fb67f56..33fcc5198446 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java @@ -9,6 +9,7 @@ import software.amazon.smithy.model.shapes.MapShape; import software.amazon.smithy.model.shapes.MemberShape; import software.amazon.smithy.model.shapes.Shape; +import software.amazon.smithy.model.traits.EnumTrait; import software.amazon.smithy.model.traits.IdempotencyTokenTrait; import software.amazon.smithy.model.traits.SensitiveTrait; import software.amazon.smithy.model.traits.SparseTrait; @@ -73,8 +74,9 @@ public static String getCppType(Shape shape, Model model) { * {@code long long} in every mapping and is unaffected. */ public static String getCppType(Shape shape, Model model, boolean wideIntegers) { - // Check enum BEFORE string — EnumShape extends StringShape in Smithy - if (shape.isEnumShape()) { + // Check enum BEFORE string — a Smithy 2.0 EnumShape extends StringShape, and a Smithy 1.0 + // enum is a plain string carrying the @enum trait; both map to the enum C++ type. + if (isEnum(shape)) { return cppShapeName(shape); } if (shape.isStringShape()) { @@ -148,7 +150,7 @@ public static String wrapSparse(Shape collectionShape, String innerType) { * @return the initializer string (e.g., {@code "0"}, {@code "false"}) or empty */ public static Optional getDefaultValue(Shape shape) { - if (shape.isEnumShape()) { + if (isEnum(shape)) { return Optional.of(cppShapeName(shape) + "::NOT_SET"); } if (shape.isIntegerShape() || shape.isLongShape()) { @@ -177,6 +179,18 @@ public static boolean isPrimitive(Shape shape) { || shape.isBooleanShape() || shape.isDoubleShape() || shape.isFloatShape(); } + /** + * Returns true if the shape is an enum — either a Smithy 2.0 {@code EnumShape} or a Smithy 1.0 + * {@code string} shape carrying the {@code @enum} trait. Both generate a dedicated C++ enum + * type. Mirrors the detection in {@code ShapeClassifier} and {@code EnumResolver}. + * + * @param shape the shape to check + * @return true if the shape maps to a generated C++ enum type + */ + public static boolean isEnum(Shape shape) { + return shape.isEnumShape() || (shape.isStringShape() && shape.hasTrait(EnumTrait.class)); + } + /** * Returns true if the shape type requires a "has been set" tracking flag. * @@ -205,8 +219,8 @@ public static boolean needsHasBeenSetFlag(Shape shape) { * @return the include path string, or empty for primitives that need no include */ public static Optional getIncludeForMemberType(Shape shape, Model model, String projectName) { - // Check enum BEFORE string — EnumShape extends StringShape in Smithy - if (shape.isEnumShape()) { + // Check enum BEFORE string — see getCppType: covers both 2.0 EnumShape and 1.0 @enum string. + if (isEnum(shape)) { return Optional.of(""); } if (shape.isStringShape()) { diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java index 2122f717e1a5..01c6a89642af 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java @@ -92,7 +92,7 @@ public void renderPublicAccessors(CppWriter writer) { if (targetShape.isDocumentShape()) { writer.write("inline Aws::Utils::DocumentView Get$L() const { return $L; }", methodName, fieldName); - } else if (isPrimitive(targetShape) || targetShape.isEnumShape()) { + } else if (isPrimitive(targetShape) || CppTypeMapper.isEnum(targetShape)) { writer.write("inline $L Get$L() const { return $L; }", cppType, methodName, fieldName); } else { writer.write("inline const $L& Get$L() const { return $L; }", cppType, methodName, fieldName); @@ -102,7 +102,7 @@ public void renderPublicAccessors(CppWriter writer) { writer.write("inline bool $LHasBeenSet() const { return $LHasBeenSet; }", methodName, fieldName); } - if (targetShape.isEnumShape() || isPrimitive(targetShape)) { + if (CppTypeMapper.isEnum(targetShape) || isPrimitive(targetShape)) { writer.openBlock("inline void Set$L($L value) {", "}", methodName, cppType, () -> { writer.write("$LHasBeenSet = true;", fieldName); writer.write("$L = value;", fieldName); @@ -291,7 +291,7 @@ private static void writeHasBeenSetFlag(CppWriter writer, MemberShape member, St * (they are cheap and trivially copyable), everything else is forwarded. */ private static boolean isByValueType(Shape shape) { - return CppTypeMapper.isPrimitive(shape) || shape.isEnumShape(); + return CppTypeMapper.isPrimitive(shape) || CppTypeMapper.isEnum(shape); } private static String capitalize(String name) { diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapperTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapperTest.java index 8bcb29075f17..62d51588de7c 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapperTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapperTest.java @@ -251,6 +251,25 @@ void enumShape_lowerCamelName_mapsToUpperCamelType() { CppTypeMapper.getIncludeForMemberType(en, model, "iam")); } + @Test + void legacyEnumStringShape_mapsToEnumType() { + // Smithy 1.0 models a closed set as a `string` shape carrying the @enum trait (not a 2.0 + // EnumShape). C2J treats these as enums, so a member targeting one must resolve to the + // enum C++ type, NOT Aws::String. Mirrors ShapeClassifier / EnumResolver detection. + software.amazon.smithy.model.traits.EnumTrait enumTrait = + software.amazon.smithy.model.traits.EnumTrait.builder() + .addEnum(software.amazon.smithy.model.traits.EnumDefinition.builder() + .value("Case.Created").name("Case_Created").build()) + .build(); + StringShape shape = StringShape.builder().id("com.example#AuditEventType") + .addTrait(enumTrait).build(); + Model model = Model.builder().addShape(shape).build(); + assertEquals("AuditEventType", CppTypeMapper.getCppType(shape, model)); + assertEquals(java.util.Optional.of("AuditEventType::NOT_SET"), CppTypeMapper.getDefaultValue(shape)); + assertEquals(java.util.Optional.of(""), + CppTypeMapper.getIncludeForMemberType(shape, model, "connectcases")); + } + @Test void structureShape_lowerCamelName_mapsToUpperCamelType() { StructureShape struct = StructureShape.builder().id("com.example#nestedThing").build(); From 24dfd8cf1d96d5395c691e357b71325edfe0dd9e Mon Sep 17 00:00:00 2001 From: sbaluja Date: Thu, 13 Aug 2026 16:30:25 -0400 Subject: [PATCH 12/19] Recursive members are std::shared_ptrs, includes, forward declares --- .../generators/model/CppTypeMapper.java | 179 ++++++++++++++++-- .../generators/model/MemberRenderer.java | 30 ++- .../model/renderers/SubObjectRenderer.java | 14 +- .../generators/model/CppTypeMapperTest.java | 109 +++++++++++ .../model/MemberRendererOutputTest.java | 46 +++++ 5 files changed, 354 insertions(+), 24 deletions(-) diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java index 33fcc5198446..3bc53142054e 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java @@ -9,12 +9,16 @@ import software.amazon.smithy.model.shapes.MapShape; import software.amazon.smithy.model.shapes.MemberShape; import software.amazon.smithy.model.shapes.Shape; +import software.amazon.smithy.model.shapes.ShapeId; import software.amazon.smithy.model.traits.EnumTrait; import software.amazon.smithy.model.traits.IdempotencyTokenTrait; import software.amazon.smithy.model.traits.SensitiveTrait; import software.amazon.smithy.model.traits.SparseTrait; +import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Deque; +import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; @@ -259,26 +263,38 @@ public static Optional getIncludeForMemberType(Shape shape, Model model, */ public static List getIncludesForShape(Shape structureShape, Model model, String projectName) { Set includes = new TreeSet<>(); + ShapeId selfId = structureShape.getId(); for (MemberShape member : structureShape.getAllMembers().values()) { Shape target = model.expectShape(member.getTarget()); - getIncludeForMemberType(target, model, projectName).ifPresent(includes::add); - // For list/map, also include the element/key/value types - if (target.isListShape()) { - ListShape list = target.asListShape().get(); - Shape elem = model.expectShape(list.getMember().getTarget()); - getIncludeForMemberType(elem, model, projectName).ifPresent(includes::add); - } - if (target.isMapShape()) { - MapShape map = target.asMapShape().get(); - Shape key = model.expectShape(map.getKey().getTarget()); - Shape value = model.expectShape(map.getValue().getTarget()); - getIncludeForMemberType(key, model, projectName).ifPresent(includes::add); - getIncludeForMemberType(value, model, projectName).ifPresent(includes::add); - } - // A @sparse list/map wraps its element/value in Aws::Crt::Optional, declared in - // . Matches C2J's generated SparseNullsOperationRequest.h. - if ((target.isListShape() || target.isMapShape()) && target.hasTrait(SparseTrait.class)) { - includes.add(""); + if (isRecursiveStructMember(structureShape, target, model)) { + // A recursive member is stored as std::shared_ptr. A mutually-referenced T is + // forward-declared (see getForwardDeclarations), so the header needs the allocator + // header for the inline MakeShared setter rather than T's own header. A directly + // self-referential member (T == enclosing) needs neither: the class declares itself + // and MakeShared resolves transitively. Both match C2J. + if (!target.getId().equals(selfId)) { + includes.add(""); + } + } else { + addMemberInclude(includes, target, selfId, model, projectName); + // For list/map, also include the element/key/value types + if (target.isListShape()) { + ListShape list = target.asListShape().get(); + addMemberInclude(includes, model.expectShape(list.getMember().getTarget()), + selfId, model, projectName); + } + if (target.isMapShape()) { + MapShape map = target.asMapShape().get(); + addMemberInclude(includes, model.expectShape(map.getKey().getTarget()), + selfId, model, projectName); + addMemberInclude(includes, model.expectShape(map.getValue().getTarget()), + selfId, model, projectName); + } + // A @sparse list/map wraps its element/value in Aws::Crt::Optional, declared in + // . Matches C2J's generated SparseNullsOperationRequest.h. + if ((target.isListShape() || target.isMapShape()) && target.hasTrait(SparseTrait.class)) { + includes.add(""); + } } // @idempotencyToken members are brace-initialized with // Aws::Utils::UUID::PseudoRandomUUID(), which requires UUID.h. Matches C2J @@ -290,4 +306,131 @@ public static List getIncludesForShape(Shape structureShape, Model model return new ArrayList<>(includes); } + /** + * Adds the member-type include for {@code shape}, unless it is the enclosing shape itself. + * C2J never emits a self-include (the class is being defined in that header); a recursive + * self-referential member reaches its own type through the shared_ptr member instead. + */ + private static void addMemberInclude(Set includes, Shape shape, ShapeId selfId, + Model model, String projectName) { + if (!shape.getId().equals(selfId)) { + getIncludeForMemberType(shape, model, projectName).ifPresent(includes::add); + } + } + + /** + * Returns the sorted C++ class names of every direct member whose target forms a reference + * cycle with {@code structureShape} (see {@link #isRecursiveStructMember}). These are stored + * as {@code std::shared_ptr} and must be forward-declared (not included) in the header to + * break the otherwise-infinite by-value member. Matches C2J's {@code computeForwardDeclarations}. + * + * @param structureShape the enclosing structure/union + * @param model the model + * @return sorted, deduplicated list of forward-declared C++ class names + */ + public static List getForwardDeclarations(Shape structureShape, Model model) { + Set names = new TreeSet<>(); + for (MemberShape member : structureShape.getAllMembers().values()) { + Shape target = model.expectShape(member.getTarget()); + // A directly self-referential member needs no forward declaration (the class declares + // itself); only distinct mutually-referenced types do. + if (isRecursiveStructMember(structureShape, target, model) + && !target.getId().equals(structureShape.getId())) { + names.add(cppShapeName(target)); + } + } + return new ArrayList<>(names); + } + + /** + * Returns the (bracket-less) model {@code #include} paths for every recursive member's target. + * The header forward-declares these types, so the {@code .cpp} must include them for the + * out-of-line MakeShared / serde bodies. Matches C2J's source-side include of the referenced type. + * + * @param structureShape the enclosing structure/union + * @param model the model + * @param projectName the service project name for model-relative includes + * @return sorted, deduplicated list of include paths without angle brackets + */ + public static List getRecursiveMemberSourceIncludes(Shape structureShape, Model model, + String projectName) { + Set inc = new TreeSet<>(); + for (MemberShape member : structureShape.getAllMembers().values()) { + Shape target = model.expectShape(member.getTarget()); + // The self header is already included by the source's base includes; only distinct + // mutually-referenced types need to be added here. + if (isRecursiveStructMember(structureShape, target, model) + && !target.getId().equals(structureShape.getId())) { + inc.add("aws/" + projectName + "/model/" + cppShapeName(target) + ".h"); + } + } + return new ArrayList<>(inc); + } + + /** + * Returns true if a direct member of {@code enclosing} whose target is {@code memberTarget} + * forms a reference cycle that must be broken with {@code std::shared_ptr}. This holds when + * {@code memberTarget} is an aggregate (structure/union) mutually referenced with + * {@code enclosing}. Members that reach back only through a list/map container do not qualify + * (the container already breaks the by-value cycle). + * + * @param enclosing the shape declaring the member + * @param memberTarget the member's direct target shape + * @param model the model + * @return true if the member must be rendered as a shared_ptr to avoid an infinite-size type + */ + public static boolean isRecursiveStructMember(Shape enclosing, Shape memberTarget, Model model) { + if (!isAggregate(memberTarget)) { + return false; + } + // C2J renders a member as shared_ptr when its target is either the enclosing shape itself + // (direct self-reference) or a distinct shape mutually referenced with it. Both otherwise + // form an infinite-size by-value member, illegal under C++11. + return memberTarget.getId().equals(enclosing.getId()) + || isMutuallyReferenced(enclosing, memberTarget, model); + } + + private static boolean isAggregate(Shape shape) { + return shape.isStructureShape() || shape.isUnionShape(); + } + + /** + * Mirrors C2J's {@code Shape.isMutuallyReferencedWith}: true when {@code a} and {@code b} are + * distinct aggregate shapes and each is reachable from the other through the member graph, + * descending one level transparently through list containers (not maps). + */ + private static boolean isMutuallyReferenced(Shape a, Shape b, Model model) { + if (a.getId().equals(b.getId()) || !isAggregate(a) || !isAggregate(b)) { + return false; + } + return reachableAggregates(a, model).contains(b.getId()) + && reachableAggregates(b, model).contains(a.getId()); + } + + private static Set reachableAggregates(Shape root, Model model) { + Set reachable = new HashSet<>(); + Set visited = new HashSet<>(); + Deque stack = new ArrayDeque<>(); + stack.push(root); + visited.add(root.getId()); + while (!stack.isEmpty()) { + Shape current = stack.pop(); + for (MemberShape member : current.getAllMembers().values()) { + // C2J descends one level through a list container (list -> element), treating the + // list edge as transparent; it does not descend through maps. + Shape target = model.expectShape(member.getTarget()); + if (target.isListShape()) { + target = model.expectShape(target.asListShape().get().getMember().getTarget()); + } + if (isAggregate(target)) { + reachable.add(target.getId()); + if (visited.add(target.getId())) { + stack.push(target); + } + } + } + } + return reachable; + } + } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java index 01c6a89642af..03221bf1fc60 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRenderer.java @@ -81,6 +81,7 @@ public void renderPublicAccessors(CppWriter writer) { String fieldName = CppNames.fieldName(memberName); String methodName = capitalize(memberName); String templateParam = methodName + "T"; + boolean recursive = isRecursiveMember(member); writer.write("///@{"); @@ -94,6 +95,9 @@ public void renderPublicAccessors(CppWriter writer) { writer.write("inline Aws::Utils::DocumentView Get$L() const { return $L; }", methodName, fieldName); } else if (isPrimitive(targetShape) || CppTypeMapper.isEnum(targetShape)) { writer.write("inline $L Get$L() const { return $L; }", cppType, methodName, fieldName); + } else if (recursive) { + // Stored as std::shared_ptr; dereference for the const-ref getter. Matches C2J. + writer.write("inline const $L& Get$L() const { return *$L; }", cppType, methodName, fieldName); } else { writer.write("inline const $L& Get$L() const { return $L; }", cppType, methodName, fieldName); } @@ -115,7 +119,15 @@ public void renderPublicAccessors(CppWriter writer) { writer.write("template ", templateParam, cppType); writer.openBlock("void Set$L($L&& value) {", "}", methodName, templateParam, () -> { writer.write("$LHasBeenSet = true;", fieldName); - writer.write("$L = std::forward<$L>(value);", fieldName, templateParam); + if (recursive) { + // Wrap the value in a shared_ptr, tagged with the enclosing class name for + // the allocator. The template setter is only instantiated at call sites, + // where T is complete, so the header can forward-declare T. Matches C2J. + writer.write("$L = Aws::MakeShared<$L>(\"$L\", std::forward<$L>(value));", + fieldName, cppType, className, templateParam); + } else { + writer.write("$L = std::forward<$L>(value);", fieldName, templateParam); + } }); writer.write("template ", templateParam, cppType); writer.openBlock("$L& With$L($L&& value) {", "}", className, methodName, templateParam, () -> { @@ -207,13 +219,20 @@ public void renderDataMembers(CppWriter writer) { entries.removeIf(e -> e.getKey().equals(exclude)); for (int i = 0; i < entries.size(); i++) { Map.Entry entry = entries.get(i); - writeDataMember(writer, entry.getValue(), entry.getKey(), model, wideIntegers); + writeDataMember(writer, entry.getValue(), entry.getKey(), model, wideIntegers, + isRecursiveMember(entry.getValue())); if (i < entries.size() - 1) { writer.write(""); } } } + /** True if this member's direct target forms a reference cycle with the enclosing shape. */ + private boolean isRecursiveMember(MemberShape member) { + Shape target = model.expectShape(member.getTarget()); + return CppTypeMapper.isRecursiveStructMember(shape, target, model); + } + /** Private {@code HasBeenSet} flags (one per member, no blank lines), skipping the excluded member. */ public void renderHasBeenSetFlags(CppWriter writer) { for (Map.Entry entry : shape.getAllMembers().entrySet()) { @@ -260,10 +279,15 @@ public static void renderRequestIdAccessors(CppWriter writer, String className) * initializer (or none). Matches C2J's ServiceClientModelHeaderMemberDeclaration.vm. */ private static void writeDataMember(CppWriter writer, MemberShape member, String memberName, Model model, - boolean wideIntegers) { + boolean wideIntegers, boolean recursive) { Shape targetShape = model.expectShape(member.getTarget()); String cppType = CppTypeMapper.getCppType(targetShape, model, wideIntegers); String fieldName = CppNames.fieldName(memberName); + if (recursive) { + // Recursive member: break the cycle with a shared_ptr (no default initializer). C2J parity. + writer.write("std::shared_ptr<$L> $L;", cppType, fieldName); + return; + } if (member.hasTrait(IdempotencyTokenTrait.class)) { writer.write("$L $L{Aws::Utils::UUID::PseudoRandomUUID()};", cppType, fieldName); return; diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/SubObjectRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/SubObjectRenderer.java index e16388688fc4..837c62e72f29 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/SubObjectRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/SubObjectRenderer.java @@ -72,6 +72,11 @@ private void renderHeader(CppWriterDelegator writerDelegator, Shape shape) { ModelFile.modelNamespace(writer, ctx.namespace(), () -> ctx.protocolTraits().writeShapeForwardDeclarations(writer), () -> { + // Recursive member targets are forward-declared here (at Model scope) instead of + // included, breaking the reference cycle. Matches C2J's computeForwardDeclarations. + for (String fwd : CppTypeMapper.getForwardDeclarations(shape, ctx.model())) { + writer.write("class $L;", fwd); + } writer.write(""); MemberRenderer.renderClassDocComment(writer, shape, ctx.smithyServiceName(), ctx.service().getVersion()); @@ -103,9 +108,12 @@ private void renderSource(CppWriterDelegator writerDelegator, Shape shape) { String fileName = "source/model/" + className + ".cpp"; writerDelegator.useFileWriter(fileName, writer -> { - IncludeSets.emitSourceIncludes(writer, - IncludeSets.subObjectSourceBase(ctx.smithyServiceName(), className), - ctx.protocolTraits(), FileKind.SUBOBJECT_SOURCE); + List sourceBase = IncludeSets.subObjectSourceBase(ctx.smithyServiceName(), className); + // Recursive member types are forward-declared in the header, so the source must include + // them for the out-of-line MakeShared / serde bodies. Matches C2J. + sourceBase.addAll(CppTypeMapper.getRecursiveMemberSourceIncludes( + shape, ctx.model(), ctx.smithyServiceName())); + IncludeSets.emitSourceIncludes(writer, sourceBase, ctx.protocolTraits(), FileKind.SUBOBJECT_SOURCE); writer.write(""); IncludeSets.emitUsings(writer, ctx.protocolTraits().serdeUsings(FileKind.SUBOBJECT_SOURCE)); diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapperTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapperTest.java index 62d51588de7c..d5e1754668d7 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapperTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapperTest.java @@ -16,6 +16,7 @@ import software.amazon.smithy.model.shapes.LongShape; import software.amazon.smithy.model.shapes.MapShape; import software.amazon.smithy.model.shapes.MemberShape; +import software.amazon.smithy.model.shapes.Shape; import software.amazon.smithy.model.shapes.StringShape; import software.amazon.smithy.model.shapes.StructureShape; import software.amazon.smithy.model.shapes.TimestampShape; @@ -314,6 +315,114 @@ void mapOfStringToStruct_mapsToAwsMap() { assertEquals("Aws::Map", CppTypeMapper.getCppType(map, model)); } + // --- recursive (mutually-referenced) shape tests --- + + /** + * Builds the connectcases-style mutual cycle: a union {@code BooleanCondition} with a direct + * member targeting struct {@code CompoundCondition}, which holds a list of + * {@code BooleanCondition}. The two aggregates are mutually referenced through the list. + */ + private static Model mutualCycleModel() { + StructureShape operands = StructureShape.builder().id("com.example#BooleanOperands").build(); + // Forward references are fine; Model.builder resolves them at build(). + UnionShape booleanCondition = UnionShape.builder() + .id("com.example#BooleanCondition") + .addMember("equalTo", operands.getId()) + .addMember("andAll", software.amazon.smithy.model.shapes.ShapeId.from("com.example#CompoundCondition")) + .build(); + ListShape conditionList = ListShape.builder() + .id("com.example#BooleanConditionList") + .member(MemberShape.builder().id("com.example#BooleanConditionList$member") + .target(booleanCondition.getId()).build()) + .build(); + StructureShape compound = StructureShape.builder() + .id("com.example#CompoundCondition") + .addMember("conditions", conditionList.getId()) + .build(); + return Model.builder().addShapes(operands, booleanCondition, conditionList, compound).build(); + } + + @Test + void mutuallyReferencedDirectMember_isRecursiveStructMember() { + Model model = mutualCycleModel(); + Shape booleanCondition = model.expectShape( + software.amazon.smithy.model.shapes.ShapeId.from("com.example#BooleanCondition")); + Shape compound = model.expectShape( + software.amazon.smithy.model.shapes.ShapeId.from("com.example#CompoundCondition")); + Shape operands = model.expectShape( + software.amazon.smithy.model.shapes.ShapeId.from("com.example#BooleanOperands")); + // andAll -> CompoundCondition is a direct member forming a cycle -> recursive + assertTrue(CppTypeMapper.isRecursiveStructMember(booleanCondition, compound, model)); + // equalTo -> BooleanOperands does not cycle back -> not recursive + assertFalse(CppTypeMapper.isRecursiveStructMember(booleanCondition, operands, model)); + } + + @Test + void recursiveMember_headerSwapsStructIncludeForAllocator_andForwardDeclares() { + Model model = mutualCycleModel(); + Shape booleanCondition = model.expectShape( + software.amazon.smithy.model.shapes.ShapeId.from("com.example#BooleanCondition")); + + List includes = CppTypeMapper.getIncludesForShape(booleanCondition, model, "connectcases"); + // The recursive CompoundCondition is forward-declared, not included; allocator comes in instead. + assertTrue(includes.contains(""), includes.toString()); + assertFalse(includes.contains(""), includes.toString()); + // Non-recursive struct member keeps its normal include. + assertTrue(includes.contains(""), includes.toString()); + + assertEquals(List.of("CompoundCondition"), + CppTypeMapper.getForwardDeclarations(booleanCondition, model)); + assertEquals(List.of("aws/connectcases/model/CompoundCondition.h"), + CppTypeMapper.getRecursiveMemberSourceIncludes(booleanCondition, model, "connectcases")); + } + + @Test + void directSelfReference_isRecursive_butNotForwardDeclaredOrSelfIncluded() { + // connectcases CaseFilter has a `not` member targeting CaseFilter itself. C2J renders it as + // std::shared_ptr but adds neither a self forward-declaration nor a self-include + // (the class declares itself) — and, unlike the mutual case, no AWSAllocator.h either. + StructureShape filter = StructureShape.builder() + .id("com.example#CaseFilter") + .addMember("not", software.amazon.smithy.model.shapes.ShapeId.from("com.example#CaseFilter")) + .build(); + Model model = Model.builder().addShape(filter).build(); + Shape caseFilter = model.expectShape( + software.amazon.smithy.model.shapes.ShapeId.from("com.example#CaseFilter")); + + assertTrue(CppTypeMapper.isRecursiveStructMember(caseFilter, caseFilter, model)); + assertEquals(List.of(), CppTypeMapper.getForwardDeclarations(caseFilter, model)); + assertEquals(List.of(), + CppTypeMapper.getRecursiveMemberSourceIncludes(caseFilter, model, "connectcases")); + List includes = CppTypeMapper.getIncludesForShape(caseFilter, model, "connectcases"); + assertFalse(includes.contains(""), + "must not self-include: " + includes); + assertFalse(includes.contains(""), + "self-reference needs no AWSAllocator.h: " + includes); + } + + @Test + void selfReferenceThroughListElement_isNotSelfIncluded() { + // CaseFilter also has andAll -> list. The list stays by-value, but its element + // include must not become a self-include. + StructureShape filter = StructureShape.builder() + .id("com.example#CaseFilter") + .addMember("andAll", software.amazon.smithy.model.shapes.ShapeId.from("com.example#CaseFilterList")) + .build(); + ListShape list = ListShape.builder() + .id("com.example#CaseFilterList") + .member(MemberShape.builder().id("com.example#CaseFilterList$member") + .target("com.example#CaseFilter").build()) + .build(); + Model model = Model.builder().addShapes(filter, list).build(); + Shape caseFilter = model.expectShape( + software.amazon.smithy.model.shapes.ShapeId.from("com.example#CaseFilter")); + + List includes = CppTypeMapper.getIncludesForShape(caseFilter, model, "connectcases"); + assertTrue(includes.contains(""), includes.toString()); + assertFalse(includes.contains(""), + "list-of-self must not self-include: " + includes); + } + // --- getDefaultValue tests --- @Test diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererOutputTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererOutputTest.java index ab92946cd6db..8eafddf2c4d5 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererOutputTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/MemberRendererOutputTest.java @@ -129,4 +129,50 @@ void sparseListAndMap_emitOptionalTypesAndAddOverloads() { out); assertTrue(out.contains("m_sparseStringMap.emplace(key, value);"), out); } + + @Test + void recursiveMember_rendersSharedPtrFieldGetterAndMakeSharedSetter() { + // Mirrors connectcases BooleanCondition.h: the andAll member targets CompoundCondition, + // which lists BooleanCondition back — a cycle C2J breaks with std::shared_ptr, a *m_x + // getter, and a MakeShared setter tagged with the enclosing class name. + StructureShape operands = StructureShape.builder().id("com.example#BooleanOperands").build(); + UnionShape booleanCondition = UnionShape.builder() + .id("com.example#BooleanCondition") + .addMember("equalTo", operands.getId()) + .addMember("andAll", software.amazon.smithy.model.shapes.ShapeId.from("com.example#CompoundCondition")) + .build(); + ListShape conditionList = ListShape.builder() + .id("com.example#BooleanConditionList") + .member(MemberShape.builder().id("com.example#BooleanConditionList$member") + .target(booleanCondition.getId()).build()) + .build(); + StructureShape compound = StructureShape.builder() + .id("com.example#CompoundCondition") + .addMember("conditions", conditionList.getId()) + .build(); + Model model = Model.builder().addShapes(operands, booleanCondition, conditionList, compound).build(); + + CppWriter pub = new CppWriter(); + MemberRenderer.forStructure(model, booleanCondition, "BooleanCondition").renderPublicAccessors(pub); + String pubOut = pub.toString(); + System.out.println(pubOut); + + // Recursive andAll: deref getter + MakeShared setter tagged with enclosing class name. + assertTrue(pubOut.contains("inline const CompoundCondition& GetAndAll() const { return *m_andAll; }"), pubOut); + assertTrue(pubOut.contains("template "), pubOut); + assertTrue(pubOut.contains( + "m_andAll = Aws::MakeShared(\"BooleanCondition\", std::forward(value));"), + pubOut); + // Non-recursive equalTo stays a plain by-value struct member. + assertTrue(pubOut.contains("inline const BooleanOperands& GetEqualTo() const { return m_equalTo; }"), pubOut); + + CppWriter priv = new CppWriter(); + MemberRenderer.forStructure(model, booleanCondition, "BooleanCondition").renderPrivateSection(priv); + String privOut = priv.toString(); + System.out.println(privOut); + + assertTrue(privOut.contains("std::shared_ptr m_andAll;"), privOut); + assertTrue(privOut.contains("BooleanOperands m_equalTo;"), privOut); + assertTrue(privOut.contains("bool m_andAllHasBeenSet = false;"), privOut); + } } From 97de9126cdec27c692a2d4b540ee92c8fa7a86f8 Mon Sep 17 00:00:00 2001 From: sbaluja Date: Thu, 13 Aug 2026 16:59:31 -0400 Subject: [PATCH 13/19] Drop deprecated members/operations --- .../model/transforms/GlobalTransforms.java | 36 +++++++- .../model/GlobalTransformsTest.java | 84 +++++++++++++++++++ 2 files changed, 118 insertions(+), 2 deletions(-) diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/transforms/GlobalTransforms.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/transforms/GlobalTransforms.java index 75f5c85f16e3..22e4a816a761 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/transforms/GlobalTransforms.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/transforms/GlobalTransforms.java @@ -17,7 +17,9 @@ import software.amazon.smithy.model.shapes.Shape; import software.amazon.smithy.model.shapes.ShapeId; import software.amazon.smithy.model.shapes.StructureShape; +import software.amazon.smithy.model.traits.DeprecatedTrait; import software.amazon.smithy.model.traits.RequiredTrait; +import software.amazon.smithy.model.transform.ModelTransformer; import java.util.ArrayDeque; import java.util.ArrayList; @@ -26,6 +28,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; /** * Global model transforms applied before code generation. @@ -135,10 +138,39 @@ public static Set computeReachableShapes(Model model, ServiceShape serv /** * Returns this class as a ModelTransform. * - *

    Currently the only pre-generation model mutation is {@link #injectResponseMetadata}. + *

    Runs {@link #dropDeprecatedMembers} first (so reachability filtering sees the pruned + * model and orphaned targets drop out), then {@link #injectResponseMetadata}. */ public static ModelTransform asTransform() { - return GlobalTransforms::injectResponseMetadata; + return (model, service) -> injectResponseMetadata(dropDeprecatedMembers(model, service), service); + } + + /** + * Removes {@code @deprecated} members from the shapes this service actually generates. This + * mirrors the legacy C2J transformer, which drops {@code "deprecated": true} member references + * ({@code C2jModelToGeneratorModelTransformer}), so deprecated members never appear in + * generated model classes. A target shape referenced only through dropped members becomes + * unreachable and is likewise omitted, matching C2J. + * + *

    Removal is scoped to members whose container is reachable from the service's operations. + * This is the "only touch what we emit" rule: it leaves framework trait definitions untouched + * (the {@code smithy.api} prelude, {@code smithy.rules}, {@code aws.*}, etc.), some of which + * declare their own {@code @deprecated} members that we must not mutate. + * + * @param model the current model + * @param service the service being generated (defines the reachable, emitted shapes) + * @return the model with deprecated members removed, or the input model if there are none + */ + public static Model dropDeprecatedMembers(Model model, ServiceShape service) { + Set reachable = computeReachableShapes(model, service); + Set deprecatedMembers = model.shapes(MemberShape.class) + .filter(member -> member.hasTrait(DeprecatedTrait.class)) + .filter(member -> reachable.contains(member.getContainer())) + .collect(Collectors.toSet()); + if (deprecatedMembers.isEmpty()) { + return model; + } + return ModelTransformer.create().removeShapes(model, deprecatedMembers); } /** diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/GlobalTransformsTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/GlobalTransformsTest.java index fd2fc0609510..d4be7bdda094 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/GlobalTransformsTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/GlobalTransformsTest.java @@ -374,6 +374,90 @@ void computeReachableShapes_errorShapes_areReachable() { assertTrue(reachable.contains(ShapeId.from("com.example#MyError"))); } + // --- dropDeprecatedMembers tests --- + + @Test + void dropDeprecatedMembers_removesDeprecatedMember_keepsOthers() { + // Mirrors C2J: a member with @deprecated is dropped from the generated shape; siblings stay. + // The shape must be reachable from the service (used as an operation input here) so that the + // reachability-scoped transform considers it. + StructureShape config = StructureShape.builder() + .id("com.example#LocationConfiguration") + .addMember(MemberShape.builder() + .id("com.example#LocationConfiguration$location").target("smithy.api#String").build()) + .addMember(MemberShape.builder() + .id("com.example#LocationConfiguration$onDemandCapacity").target("smithy.api#Integer") + .addTrait(software.amazon.smithy.model.traits.DeprecatedTrait.builder().build()) + .build()) + .build(); + StructureShape output = StructureShape.builder().id("com.example#MyOutput").build(); + OperationShape op = OperationShape.builder() + .id("com.example#MyOperation").input(config.getId()).output(output.getId()).build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#MyService").version("2024-01-01").addOperation(op.getId()).build(); + Model model = Model.assembler().addShapes(config, output, op, service).assemble().unwrap(); + + Model out = GlobalTransforms.dropDeprecatedMembers(model, service); + StructureShape transformed = out.expectShape( + ShapeId.from("com.example#LocationConfiguration"), StructureShape.class); + assertFalse(transformed.getMember("onDemandCapacity").isPresent(), + "deprecated member must be dropped"); + assertTrue(transformed.getMember("location").isPresent(), + "non-deprecated sibling must remain"); + } + + @Test + void dropDeprecatedMembers_noDeprecated_returnsSameModel() { + StructureShape input = StructureShape.builder() + .id("com.example#MyInput") + .addMember(MemberShape.builder().id("com.example#MyInput$a").target("smithy.api#String").build()) + .build(); + StructureShape output = StructureShape.builder().id("com.example#MyOutput").build(); + OperationShape op = OperationShape.builder() + .id("com.example#MyOperation").input(input.getId()).output(output.getId()).build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#MyService").version("2024-01-01").addOperation(op.getId()).build(); + Model model = Model.assembler().addShapes(input, output, op, service).assemble().unwrap(); + // The prelude declares its own @deprecated member (protocolDefinition$noInlineDocumentSupport), + // but it is not reachable from the service, so the transform is a true no-op here. + assertSame(model, GlobalTransforms.dropDeprecatedMembers(model, service), + "models without service-reachable deprecated members should be returned unchanged"); + } + + @Test + void dropDeprecatedMembers_orphanedTargetBecomesUnreachable() { + // A struct referenced ONLY through a deprecated member drops out of the reachable set, + // matching C2J's omission of the orphaned shape file. + StructureShape orphan = StructureShape.builder() + .id("com.example#OrphanDetail") + .addMember(MemberShape.builder() + .id("com.example#OrphanDetail$x").target("smithy.api#String").build()) + .build(); + StructureShape input = StructureShape.builder() + .id("com.example#MyInput") + .addMember(MemberShape.builder() + .id("com.example#MyInput$detail").target(orphan.getId()) + .addTrait(software.amazon.smithy.model.traits.DeprecatedTrait.builder().build()) + .build()) + .build(); + StructureShape output = StructureShape.builder().id("com.example#MyOutput").build(); + OperationShape op = OperationShape.builder() + .id("com.example#MyOperation").input(input.getId()).output(output.getId()).build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#MyService").version("2024-01-01").addOperation(op.getId()).build(); + Model model = Model.assembler() + .addShapes(orphan, input, output, op, service).assemble().unwrap(); + + Model out = GlobalTransforms.dropDeprecatedMembers(model, service); + Set reachable = GlobalTransforms.computeReachableShapes(out, serviceOf(out, "MyService")); + assertFalse(reachable.contains(ShapeId.from("com.example#OrphanDetail")), + "shape referenced only via a deprecated member must become unreachable"); + } + + private static ServiceShape serviceOf(Model model, String name) { + return model.expectShape(ShapeId.from("com.example#" + name), ServiceShape.class); + } + // --- injectResponseMetadata tests --- /** A single-operation service under the given protocol trait, output has one plain member. */ From 328b82c4dc0ea57e4806aba154ee15ba4cdc33dd Mon Sep 17 00:00:00 2001 From: sbaluja Date: Thu, 13 Aug 2026 20:53:18 -0400 Subject: [PATCH 14/19] Request compression trait handling --- .../model/renderers/RequestRenderer.java | 77 ++++++++++ .../generators/model/RequestRendererTest.java | 144 ++++++++++++++++++ 2 files changed, 221 insertions(+) diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java index 1bf02659ee90..b6544c0d0673 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java @@ -22,6 +22,7 @@ import software.amazon.smithy.model.shapes.OperationShape; import software.amazon.smithy.model.shapes.StructureShape; import software.amazon.smithy.model.traits.DocumentationTrait; +import software.amazon.smithy.model.traits.RequestCompressionTrait; import software.amazon.smithy.rulesengine.traits.ContextParamTrait; import software.amazon.smithy.rulesengine.traits.StaticContextParamsTrait; @@ -141,6 +142,10 @@ private void renderHeader(CppWriterDelegator writerDelegator, writer.write("$L std::shared_ptr GetBody() const override;", ctx.exportMacro()); } ctx.protocolTraits().writeRequestMethodDecls(writer, ctx.exportMacro(), shape, operation, ctx.model()); + // Request-feature methods driven by operation traits. Today: @requestCompression. + // @httpChecksum (aws.protocols) for s3 will render alongside here when s3 moves to + // the Smithy path (its own transform pipeline supplies the model; this seam stays). + renderRequestCompressionDecl(writer, operation); if (streamingResponse) { String handlerType = operation.getId().getName() + "Handler"; @@ -259,6 +264,7 @@ private void renderSource(CppWriterDelegator writerDelegator, }); // Header/query method bodies (SerializePayload is gated off for streaming requests). ctx.protocolTraits().writeRequestMethodImpls(writer, className, shape, operation, ctx.service(), ctx.model()); + renderRequestCompressionImpl(writer, className, operation, true); if (hasEndpointContextParams(operation, shape)) { writer.write(""); renderEndpointContextParams(writer, className, operation, shape); @@ -277,6 +283,7 @@ private void renderSource(CppWriterDelegator writerDelegator, writer.write(""); ctx.protocolTraits().writeRequestMethodImpls(writer, className, shape, operation, ctx.service(), ctx.model()); + renderRequestCompressionImpl(writer, className, operation, false); if (hasEndpointContextParams(operation, shape)) { writer.write(""); @@ -360,6 +367,76 @@ private void renderEventStreamMemberAccessor(CppWriter writer, String className, writer.write("///@}"); } + /** + * Declares {@code GetSelectedCompressionAlgorithm} for an operation carrying + * {@code @requestCompression}. The method overrides a base {@code AmazonWebServiceRequest} + * virtual, so no extra include is needed. Only gzip is supported (validated), so the + * declaration is always guarded by {@code ENABLED_ZLIB_REQUEST_COMPRESSION}. Matches C2J's + * {@code RequestHeader.vm}. + */ + private void renderRequestCompressionDecl(CppWriter writer, OperationShape operation) { + if (!operation.hasTrait(RequestCompressionTrait.class)) { + return; + } + validateGzipEncoding(operation); + writer.write(""); + writer.write("#ifdef ENABLED_ZLIB_REQUEST_COMPRESSION"); + writer.write("virtual Aws::Client::CompressionAlgorithm GetSelectedCompressionAlgorithm(Aws::Client::RequestCompressionConfig config) const override;"); + writer.write("#endif"); + } + + /** + * Defines {@code GetSelectedCompressionAlgorithm}. Streaming requests can't size their body up + * front, so they compress whenever enabled; non-streaming requests skip compression below the + * configured minimum body size. Matches C2J's ModelClassRequiredCompression[Stream].vm. This + * body only reads the already-serialized body via the base {@code GetBody()}, so it is + * independent of the (currently stubbed) payload serde. + */ + private void renderRequestCompressionImpl(CppWriter writer, String className, + OperationShape operation, boolean streaming) { + if (!operation.hasTrait(RequestCompressionTrait.class)) { + return; + } + writer.write("#ifdef ENABLED_ZLIB_REQUEST_COMPRESSION"); + writer.openBlock("Aws::Client::CompressionAlgorithm $L::GetSelectedCompressionAlgorithm(Aws::Client::RequestCompressionConfig config) const {", "}", + className, () -> { + writer.openBlock("if (config.useRequestCompression == Aws::Client::UseRequestCompression::DISABLE) {", "}", () -> + writer.write("return Aws::Client::CompressionAlgorithm::NONE;")); + if (streaming) { + writer.openBlock("else {", "}", () -> + writer.write("return Aws::Client::CompressionAlgorithm::GZIP;")); + } else { + writer.write(""); + writer.write("const auto& body = AmazonSerializableWebServiceRequest::GetBody();"); + writer.write("body->seekg(0, body->end);"); + writer.write("size_t bodySize = body->tellg();"); + writer.write("body->seekg(0, body->beg);"); + writer.openBlock("if (bodySize < config.requestMinCompressionSizeBytes) {", "}", () -> + writer.write("return Aws::Client::CompressionAlgorithm::NONE;")); + writer.openBlock("else {", "}", () -> + writer.write("return Aws::Client::CompressionAlgorithm::GZIP;")); + } + }); + writer.write("#endif"); + } + + /** + * Enforces the C2J contract that {@code @requestCompression} declares exactly the gzip encoding + * (the only algorithm the SDK supports). Fails fast on an empty or unsupported encoding list, + * mirroring the legacy C2J transformer. + */ + private static void validateGzipEncoding(OperationShape operation) { + List encodings = operation.expectTrait(RequestCompressionTrait.class).getEncodings(); + if (encodings.isEmpty()) { + throw new RuntimeException("@requestCompression on " + operation.getId() + + " must declare at least one encoding."); + } + if (encodings.size() != 1 || !"gzip".equals(encodings.get(0))) { + throw new RuntimeException("@requestCompression only supports the gzip algorithm, but " + + operation.getId() + " declares: " + encodings); + } + } + private boolean hasEndpointContextParams(OperationShape operation, StructureShape shape) { if (operation.hasTrait(StaticContextParamsTrait.class)) { return true; diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RequestRendererTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RequestRendererTest.java index 86b992ece52d..5cd33cb0f9a8 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RequestRendererTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RequestRendererTest.java @@ -351,6 +351,150 @@ private static String renderRawStreamingPayloadRestJsonRequest(String fileSuffix .filter(p -> p.toString().endsWith(fileSuffix)).findFirst().orElseThrow()).orElseThrow(); } + // --- @requestCompression --- + + /** + * Model for a JSON operation carrying {@code @requestCompression(encodings: ["gzip"])} on + * either a plain input (streaming = false) or a raw {@code @httpPayload} blob body input + * (streaming = true). + */ + private static Model requestCompressionModel(boolean streaming, java.util.List encodings) { + StringShape str = StringShape.builder().id("com.example#String").build(); + StructureShape.Builder input = StructureShape.builder().id("com.example#PutThingInput"); + if (streaming) { + software.amazon.smithy.model.shapes.BlobShape blob = + software.amazon.smithy.model.shapes.BlobShape.builder().id("com.example#Body").build(); + input.addMember(MemberShape.builder() + .id("com.example#PutThingInput$body").target(blob.getId()) + .addTrait(new software.amazon.smithy.model.traits.HttpPayloadTrait()).build()); + input.addMember(MemberShape.builder() + .id("com.example#PutThingInput$contentType").target(str.getId()) + .addTrait(new software.amazon.smithy.model.traits.HttpHeaderTrait("Content-Type")).build()); + Model.Builder mb = Model.builder().addShape(blob); + return finishCompressionModel(mb, str, input.build(), encodings); + } + input.addMember("name", str.getId()); + return finishCompressionModel(Model.builder(), str, input.build(), encodings); + } + + private static Model finishCompressionModel(Model.Builder mb, StringShape str, + StructureShape input, java.util.List encodings) { + StructureShape output = StructureShape.builder().id("com.example#PutThingOutput") + .addMember("r", str.getId()).build(); + OperationShape op = OperationShape.builder() + .id("com.example#PutThing").input(input.getId()).output(output.getId()) + .addTrait(software.amazon.smithy.model.traits.RequestCompressionTrait.builder() + .encodings(encodings).build()) + .build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#Example").version("2024-01-01").addOperation(op.getId()).build(); + return mb.addShapes(str, input, output, op, service).build(); + } + + private static String renderCompressionRequest(boolean streaming, String fileSuffix) { + Model model = requestCompressionModel(streaming, java.util.List.of("gzip")); + ServiceShape service = model.expectShape(ShapeId.from("com.example#Example"), ServiceShape.class); + MockManifest manifest = new MockManifest(); + CppWriterDelegator delegator = new CppWriterDelegator(manifest); + Protocol protocol = ProtocolResolver.resolve(service, model); + new RequestRenderer( + ShapeClassifier.classify(model, service, protocol).requests(), + new RenderContext(model, service, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example")).render(delegator); + delegator.flushWriters(); + return manifest.getFileString(manifest.getFiles().stream() + .filter(p -> p.toString().endsWith(fileSuffix)).findFirst().orElseThrow()).orElseThrow(); + } + + @Test + void requestCompressionGzip_headerDeclaresGuardedVirtualOverride() { + // C2J's RequestHeader.vm:148-156 emits GetSelectedCompressionAlgorithm as a virtual override + // gated by ENABLED_ZLIB_REQUEST_COMPRESSION. The types (CompressionAlgorithm, + // RequestCompressionConfig) come from the base AmazonWebServiceRequest.h transitively — + // NO extra include in the request header. + String h = renderCompressionRequest(false, "PutThingRequest.h"); + assertTrue(h.contains("#ifdef ENABLED_ZLIB_REQUEST_COMPRESSION"), + "Missing ENABLED_ZLIB_REQUEST_COMPRESSION guard: " + h); + assertTrue(h.contains( + "virtual Aws::Client::CompressionAlgorithm GetSelectedCompressionAlgorithm(Aws::Client::RequestCompressionConfig config) const override;"), + "Missing GetSelectedCompressionAlgorithm decl: " + h); + assertFalse(h.contains("#include NONE, then read the + // already-serialized body via AmazonSerializableWebServiceRequest::GetBody(), compare its + // size to config.requestMinCompressionSizeBytes, and either NONE or GZIP. Matches cloudwatch + // PutMetricDataRequest.cpp exactly. Body only touches base state; NOT serde-blocked. + String c = renderCompressionRequest(false, "PutThingRequest.cpp"); + assertTrue(c.contains("#ifdef ENABLED_ZLIB_REQUEST_COMPRESSION"), c); + assertTrue(c.contains( + "Aws::Client::CompressionAlgorithm PutThingRequest::GetSelectedCompressionAlgorithm(Aws::Client::RequestCompressionConfig config) const {"), + c); + assertTrue(c.contains("config.useRequestCompression == Aws::Client::UseRequestCompression::DISABLE"), c); + assertTrue(c.contains("const auto& body = AmazonSerializableWebServiceRequest::GetBody();"), c); + assertTrue(c.contains("bodySize < config.requestMinCompressionSizeBytes"), c); + assertTrue(c.contains("return Aws::Client::CompressionAlgorithm::NONE;"), c); + assertTrue(c.contains("return Aws::Client::CompressionAlgorithm::GZIP;"), c); + } + + @Test + void requestCompressionGzip_streamingSourceCompressesWheneverEnabled() { + // Streaming variant (ModelClassRequiredCompressionStream.vm): the body isn't sized up front, + // so DISABLE -> NONE, else GZIP unconditionally. No body-size check. + String c = renderCompressionRequest(true, "PutThingRequest.cpp"); + assertTrue(c.contains("#ifdef ENABLED_ZLIB_REQUEST_COMPRESSION"), c); + assertTrue(c.contains("PutThingRequest::GetSelectedCompressionAlgorithm"), c); + assertTrue(c.contains("return Aws::Client::CompressionAlgorithm::GZIP;"), c); + assertFalse(c.contains("requestMinCompressionSizeBytes"), + "Streaming variant must not do a body-size check: " + c); + assertFalse(c.contains("AmazonSerializableWebServiceRequest::GetBody"), + "Streaming variant must not query the body: " + c); + } + + @Test + void requestCompression_nonGzipEncoding_throws() { + // C2J transformer:795-800 rejects non-gzip encodings; the plugin must match. Rendering + // aborts at request time (the renderer walks operations and encounters the trait). + Model model = requestCompressionModel(false, java.util.List.of("deflate")); + ServiceShape service = model.expectShape(ShapeId.from("com.example#Example"), ServiceShape.class); + MockManifest manifest = new MockManifest(); + CppWriterDelegator delegator = new CppWriterDelegator(manifest); + Protocol protocol = ProtocolResolver.resolve(service, model); + RequestRenderer renderer = new RequestRenderer( + ShapeClassifier.classify(model, service, protocol).requests(), + new RenderContext(model, service, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example")); + RuntimeException ex = org.junit.jupiter.api.Assertions.assertThrows( + RuntimeException.class, () -> renderer.render(delegator)); + assertTrue(ex.getMessage().contains("gzip"), "Should mention gzip: " + ex.getMessage()); + } + + @Test + void requestWithoutCompressionTrait_emitsNothingCompressionRelated() { + // Regression guard: operations without @requestCompression must not gain the override or + // its #ifdef. Reuses the query-member model which has no compression trait. + Model model = queryMemberModel(); + ServiceShape service = model.expectShape(ShapeId.from("com.example#Example"), ServiceShape.class); + MockManifest manifest = new MockManifest(); + CppWriterDelegator delegator = new CppWriterDelegator(manifest); + Protocol protocol = ProtocolResolver.resolve(service, model); + new RequestRenderer( + ShapeClassifier.classify(model, service, protocol).requests(), + new RenderContext(model, service, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example")).render(delegator); + delegator.flushWriters(); + String h = manifest.getFileString(manifest.getFiles().stream() + .filter(p -> p.toString().endsWith("DoThingRequest.h")).findFirst().orElseThrow()).orElseThrow(); + String c = manifest.getFileString(manifest.getFiles().stream() + .filter(p -> p.toString().endsWith("DoThingRequest.cpp")).findFirst().orElseThrow()).orElseThrow(); + assertFalse(h.contains("GetSelectedCompressionAlgorithm"), h); + assertFalse(c.contains("GetSelectedCompressionAlgorithm"), c); + assertFalse(h.contains("ENABLED_ZLIB_REQUEST_COMPRESSION"), h); + } + @Test void rawStreamingPayloadRequestRestJson_headerAndSourceAgreeOnRequestSpecificHeaders() { // Under a REST protocol (hasTargetHeader() == false), a raw-streaming-payload request whose From 854b4212f4bf380c7f119a5127b6986d760a7958 Mon Sep 17 00:00:00 2001 From: sbaluja Date: Thu, 13 Aug 2026 21:42:42 -0400 Subject: [PATCH 15/19] Add codegen for httpChecksum related traits --- .../model/renderers/RequestRenderer.java | 114 ++++++++++++- .../generators/model/RequestRendererTest.java | 151 ++++++++++++++++++ 2 files changed, 262 insertions(+), 3 deletions(-) diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java index b6544c0d0673..3751644a1187 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/renderers/RequestRenderer.java @@ -18,10 +18,12 @@ import software.amazon.smithy.model.node.Node; import software.amazon.smithy.model.node.NodeVisitor; import software.amazon.smithy.model.node.StringNode; +import software.amazon.smithy.aws.traits.HttpChecksumTrait; import software.amazon.smithy.model.shapes.MemberShape; import software.amazon.smithy.model.shapes.OperationShape; import software.amazon.smithy.model.shapes.StructureShape; import software.amazon.smithy.model.traits.DocumentationTrait; +import software.amazon.smithy.model.traits.HttpChecksumRequiredTrait; import software.amazon.smithy.model.traits.RequestCompressionTrait; import software.amazon.smithy.rulesengine.traits.ContextParamTrait; import software.amazon.smithy.rulesengine.traits.StaticContextParamsTrait; @@ -142,9 +144,10 @@ private void renderHeader(CppWriterDelegator writerDelegator, writer.write("$L std::shared_ptr GetBody() const override;", ctx.exportMacro()); } ctx.protocolTraits().writeRequestMethodDecls(writer, ctx.exportMacro(), shape, operation, ctx.model()); - // Request-feature methods driven by operation traits. Today: @requestCompression. - // @httpChecksum (aws.protocols) for s3 will render alongside here when s3 moves to - // the Smithy path (its own transform pipeline supplies the model; this seam stays). + // Request-feature methods driven by operation traits, in C2J RequestHeader.vm order: + // @httpChecksum, @httpChecksumRequired (legacy Content-MD5), then @requestCompression. + renderChecksumDecls(writer, shape, operation); + renderContentMd5Decl(writer, operation); renderRequestCompressionDecl(writer, operation); if (streamingResponse) { @@ -264,6 +267,7 @@ private void renderSource(CppWriterDelegator writerDelegator, }); // Header/query method bodies (SerializePayload is gated off for streaming requests). ctx.protocolTraits().writeRequestMethodImpls(writer, className, shape, operation, ctx.service(), ctx.model()); + renderChecksumImpls(writer, className, shape, operation); renderRequestCompressionImpl(writer, className, operation, true); if (hasEndpointContextParams(operation, shape)) { writer.write(""); @@ -283,6 +287,7 @@ private void renderSource(CppWriterDelegator writerDelegator, writer.write(""); ctx.protocolTraits().writeRequestMethodImpls(writer, className, shape, operation, ctx.service(), ctx.model()); + renderChecksumImpls(writer, className, shape, operation); renderRequestCompressionImpl(writer, className, operation, false); if (hasEndpointContextParams(operation, shape)) { @@ -367,6 +372,109 @@ private void renderEventStreamMemberAccessor(CppWriter writer, String className, writer.write("///@}"); } + /** + * Declares the request methods for an operation carrying {@code @httpChecksum}, gated per + * sub-field, matching C2J's RequestHeader.vm:89-104: + *

      + *
    • {@code requestAlgorithmMember} → {@code GetChecksumAlgorithmName} / {@code ChecksumAlgorithmIsSet}
    • + *
    • {@code requestValidationModeMember} → {@code ShouldValidateResponseChecksum}
    • + *
    • {@code requestChecksumRequired} → inline {@code RequestChecksumRequired}
    • + *
    • {@code responseAlgorithms} → {@code GetResponseChecksumAlgorithmNames}
    • + *
    + * All override base {@code AmazonWebServiceRequest} virtuals; no extra includes are needed. + */ + private void renderChecksumDecls(CppWriter writer, StructureShape shape, OperationShape operation) { + Optional maybeTrait = operation.getTrait(HttpChecksumTrait.class); + if (maybeTrait.isEmpty()) { + return; + } + HttpChecksumTrait trait = maybeTrait.get(); + if (trait.getRequestAlgorithmMember().isPresent()) { + writer.write("$L Aws::String GetChecksumAlgorithmName() const override;", ctx.exportMacro()); + writer.write("$L bool ChecksumAlgorithmIsSet() const override;", ctx.exportMacro()); + } + if (trait.getRequestValidationModeMember().isPresent()) { + writer.write("$L bool ShouldValidateResponseChecksum() const override;", ctx.exportMacro()); + } + if (trait.isRequestChecksumRequired()) { + writer.write("inline bool RequestChecksumRequired() const override { return true; };"); + } + if (!trait.getResponseAlgorithms().isEmpty()) { + writer.write("$L Aws::Vector GetResponseChecksumAlgorithmNames() const override;", ctx.exportMacro()); + } + } + + /** + * Defines the {@code @httpChecksum} request methods, matching C2J's ModelClassChecksumMembers.vm. + * {@code GetChecksumAlgorithmName} defaults to {@code "crc64nvme"} when the algorithm member is + * unset, else maps the enum via its generated Mapper. The bodies read only the request's own + * enum members, so they are independent of the (stubbed) payload serde. + */ + private void renderChecksumImpls(CppWriter writer, String className, StructureShape shape, + OperationShape operation) { + Optional maybeTrait = operation.getTrait(HttpChecksumTrait.class); + if (maybeTrait.isEmpty()) { + return; + } + HttpChecksumTrait trait = maybeTrait.get(); + trait.getRequestAlgorithmMember().ifPresent(memberName -> { + String enumType = checksumMemberEnumType(shape, operation, memberName); + String field = CppNames.fieldName(memberName); + writer.openBlock("Aws::String $L::GetChecksumAlgorithmName() const {", "}", className, () -> { + writer.openBlock("if ($L == $L::NOT_SET) {", "}", field, enumType, () -> + writer.write("return \"crc64nvme\";")); + writer.openBlock("else {", "}", () -> + writer.write("return $1LMapper::GetNameFor$1L($2L);", enumType, field)); + }); + writer.write(""); + writer.openBlock("bool $L::ChecksumAlgorithmIsSet() const {", "}", className, () -> + writer.write("return $L != $L::NOT_SET;", field, enumType)); + writer.write(""); + }); + trait.getRequestValidationModeMember().ifPresent(memberName -> { + String enumType = checksumMemberEnumType(shape, operation, memberName); + String field = CppNames.fieldName(memberName); + writer.openBlock("bool $L::ShouldValidateResponseChecksum() const {", "}", className, () -> + writer.write("return $L == $L::ENABLED;", field, enumType)); + writer.write(""); + }); + if (!trait.getResponseAlgorithms().isEmpty()) { + writer.openBlock("Aws::Vector $L::GetResponseChecksumAlgorithmNames() const {", "}", + className, () -> { + writer.write("Aws::Vector responseChecksumAlgorithmNames;"); + for (String algorithm : trait.getResponseAlgorithms()) { + writer.write("responseChecksumAlgorithmNames.push_back(\"$L\");", algorithm); + } + writer.write("return responseChecksumAlgorithmNames;"); + }); + writer.write(""); + } + } + + /** + * Declares the inline {@code ShouldComputeContentMd5} override for an operation carrying the + * legacy {@code @httpChecksumRequired} trait ({@code smithy.api#httpChecksumRequired}), which + * requests a {@code Content-MD5} header. Distinct from the flexible {@code @httpChecksum} trait. + * C2J derives an internal {@code Shape.computeContentMd5} flag from it; here it reads the trait + * directly. Matches RequestHeader.vm:105-108 (no {@code .cpp} body). + */ + private void renderContentMd5Decl(CppWriter writer, OperationShape operation) { + if (operation.hasTrait(HttpChecksumRequiredTrait.class)) { + writer.write(""); + writer.write("$L inline bool ShouldComputeContentMd5() const override { return true; }", ctx.exportMacro()); + } + } + + /** The C++ enum type name of a checksum algorithm/validation-mode member named by @httpChecksum. */ + private String checksumMemberEnumType(StructureShape shape, OperationShape operation, String memberName) { + MemberShape member = shape.getAllMembers().get(memberName); + if (member == null) { + throw new RuntimeException("@httpChecksum on " + operation.getId() + + " references member '" + memberName + "' not present on " + shape.getId()); + } + return CppTypeMapper.cppShapeName(ctx.model().expectShape(member.getTarget())); + } + /** * Declares {@code GetSelectedCompressionAlgorithm} for an operation carrying * {@code @requestCompression}. The method overrides a base {@code AmazonWebServiceRequest} diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RequestRendererTest.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RequestRendererTest.java index 5cd33cb0f9a8..fa3614153182 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RequestRendererTest.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/test/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/RequestRendererTest.java @@ -351,6 +351,157 @@ private static String renderRawStreamingPayloadRestJsonRequest(String fileSuffix .filter(p -> p.toString().endsWith(fileSuffix)).findFirst().orElseThrow()).orElseThrow(); } + // --- @httpChecksum --- + + /** + * A JSON operation with @httpChecksum. The input carries a {@code checksumAlgorithm} enum member + * (for requestAlgorithmMember) and a {@code checksumMode} enum member (for + * requestValidationModeMember); the trait is configured from the given values. + */ + private static Model httpChecksumModel(software.amazon.smithy.aws.traits.HttpChecksumTrait trait) { + StringShape str = StringShape.builder().id("com.example#String").build(); + software.amazon.smithy.model.shapes.EnumShape algo = + software.amazon.smithy.model.shapes.EnumShape.builder() + .id("com.example#ChecksumAlgorithm").addMember("CRC32", "CRC32").build(); + software.amazon.smithy.model.shapes.EnumShape mode = + software.amazon.smithy.model.shapes.EnumShape.builder() + .id("com.example#ChecksumMode").addMember("ENABLED", "ENABLED").build(); + StructureShape input = StructureShape.builder() + .id("com.example#PutThingInput") + .addMember("checksumAlgorithm", algo.getId()) + .addMember("checksumMode", mode.getId()) + .addMember("name", str.getId()) + .build(); + StructureShape output = StructureShape.builder().id("com.example#PutThingOutput") + .addMember("r", str.getId()).build(); + OperationShape op = OperationShape.builder() + .id("com.example#PutThing").input(input.getId()).output(output.getId()) + .addTrait(trait).build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#Example").version("2024-01-01").addOperation(op.getId()).build(); + return Model.builder().addShapes(str, algo, mode, input, output, op, service).build(); + } + + private static String renderChecksumRequest(software.amazon.smithy.aws.traits.HttpChecksumTrait trait, + String fileSuffix) { + Model model = httpChecksumModel(trait); + ServiceShape service = model.expectShape(ShapeId.from("com.example#Example"), ServiceShape.class); + MockManifest manifest = new MockManifest(); + CppWriterDelegator delegator = new CppWriterDelegator(manifest); + Protocol protocol = ProtocolResolver.resolve(service, model); + new RequestRenderer( + ShapeClassifier.classify(model, service, protocol).requests(), + new RenderContext(model, service, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example")).render(delegator); + delegator.flushWriters(); + return manifest.getFileString(manifest.getFiles().stream() + .filter(p -> p.toString().endsWith(fileSuffix)).findFirst().orElseThrow()).orElseThrow(); + } + + @Test + void httpChecksumRequestAlgorithm_rendersAlgorithmNameAndIsSet() { + // requestAlgorithmMember → GetChecksumAlgorithmName (crc64nvme default, else Mapper) + + // ChecksumAlgorithmIsSet. Matches C2J ModelClassChecksumMembers.vm / PutObjectRequest. + software.amazon.smithy.aws.traits.HttpChecksumTrait trait = + software.amazon.smithy.aws.traits.HttpChecksumTrait.builder() + .requestAlgorithmMember("checksumAlgorithm").build(); + String h = renderChecksumRequest(trait, "PutThingRequest.h"); + String c = renderChecksumRequest(trait, "PutThingRequest.cpp"); + + assertTrue(h.contains("AWS_EXAMPLE_API Aws::String GetChecksumAlgorithmName() const override;"), h); + assertTrue(h.contains("AWS_EXAMPLE_API bool ChecksumAlgorithmIsSet() const override;"), h); + + assertTrue(c.contains("Aws::String PutThingRequest::GetChecksumAlgorithmName() const {"), c); + assertTrue(c.contains("if (m_checksumAlgorithm == ChecksumAlgorithm::NOT_SET) {"), c); + assertTrue(c.contains("return \"crc64nvme\";"), c); + assertTrue(c.contains("return ChecksumAlgorithmMapper::GetNameForChecksumAlgorithm(m_checksumAlgorithm);"), c); + assertTrue(c.contains("return m_checksumAlgorithm != ChecksumAlgorithm::NOT_SET;"), c); + } + + @Test + void httpChecksumValidationAndResponseAlgorithms_render() { + // requestValidationModeMember → ShouldValidateResponseChecksum; responseAlgorithms → + // GetResponseChecksumAlgorithmNames (one push_back per algorithm, in order). + software.amazon.smithy.aws.traits.HttpChecksumTrait trait = + software.amazon.smithy.aws.traits.HttpChecksumTrait.builder() + .requestValidationModeMember("checksumMode") + .responseAlgorithms(java.util.List.of("CRC64NVME", "CRC32")).build(); + String h = renderChecksumRequest(trait, "PutThingRequest.h"); + String c = renderChecksumRequest(trait, "PutThingRequest.cpp"); + + assertTrue(h.contains("AWS_EXAMPLE_API bool ShouldValidateResponseChecksum() const override;"), h); + assertTrue(h.contains("AWS_EXAMPLE_API Aws::Vector GetResponseChecksumAlgorithmNames() const override;"), h); + + assertTrue(c.contains("return m_checksumMode == ChecksumMode::ENABLED;"), c); + assertTrue(c.contains("responseChecksumAlgorithmNames.push_back(\"CRC64NVME\");"), c); + assertTrue(c.contains("responseChecksumAlgorithmNames.push_back(\"CRC32\");"), c); + assertTrue(c.contains("return responseChecksumAlgorithmNames;"), c); + } + + @Test + void httpChecksumRequestChecksumRequired_rendersInlineOverride() { + // requestChecksumRequired → inline RequestChecksumRequired() in the header (no .cpp body), + // matching C2J's PutBucketPolicyRequest.h (note the trailing semicolon after the brace). + software.amazon.smithy.aws.traits.HttpChecksumTrait trait = + software.amazon.smithy.aws.traits.HttpChecksumTrait.builder() + .requestAlgorithmMember("checksumAlgorithm").requestChecksumRequired(true).build(); + String h = renderChecksumRequest(trait, "PutThingRequest.h"); + assertTrue(h.contains("inline bool RequestChecksumRequired() const override { return true; };"), h); + } + + @Test + void httpChecksumRequired_rendersInlineShouldComputeContentMd5() { + // The legacy smithy.api#httpChecksumRequired trait (s3control uses it) requests a + // Content-MD5 header. C2J derives Shape.computeContentMd5 from it and emits an inline + // ShouldComputeContentMd5() override (RequestHeader.vm:105-108, no .cpp body). Distinct + // from the flexible @httpChecksum trait. + StringShape str = StringShape.builder().id("com.example#String").build(); + StructureShape input = StructureShape.builder().id("com.example#PutThingInput") + .addMember("name", str.getId()).build(); + StructureShape output = StructureShape.builder().id("com.example#PutThingOutput") + .addMember("r", str.getId()).build(); + OperationShape op = OperationShape.builder() + .id("com.example#PutThing").input(input.getId()).output(output.getId()) + .addTrait(new software.amazon.smithy.model.traits.HttpChecksumRequiredTrait()).build(); + ServiceShape service = ServiceShape.builder() + .id("com.example#Example").version("2024-01-01").addOperation(op.getId()).build(); + Model model = Model.builder().addShapes(str, input, output, op, service).build(); + + ServiceShape svc = model.expectShape(ShapeId.from("com.example#Example"), ServiceShape.class); + MockManifest manifest = new MockManifest(); + CppWriterDelegator delegator = new CppWriterDelegator(manifest); + Protocol protocol = ProtocolResolver.resolve(svc, model); + new RequestRenderer( + ShapeClassifier.classify(model, svc, protocol).requests(), + new RenderContext(model, svc, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example")).render(delegator); + delegator.flushWriters(); + String h = manifest.getFileString(manifest.getFiles().stream() + .filter(p -> p.toString().endsWith("PutThingRequest.h")).findFirst().orElseThrow()).orElseThrow(); + String c = manifest.getFileString(manifest.getFiles().stream() + .filter(p -> p.toString().endsWith("PutThingRequest.cpp")).findFirst().orElseThrow()).orElseThrow(); + assertTrue(h.contains("AWS_EXAMPLE_API inline bool ShouldComputeContentMd5() const override { return true; }"), h); + assertFalse(c.contains("ShouldComputeContentMd5"), "inline method must have no out-of-line body: " + c); + } + + @Test + void requestWithoutHttpChecksum_emitsNoChecksumMethods() { + Model model = queryMemberModel(); + ServiceShape service = model.expectShape(ShapeId.from("com.example#Example"), ServiceShape.class); + MockManifest manifest = new MockManifest(); + CppWriterDelegator delegator = new CppWriterDelegator(manifest); + Protocol protocol = ProtocolResolver.resolve(service, model); + new RequestRenderer( + ShapeClassifier.classify(model, service, protocol).requests(), + new RenderContext(model, service, ProtocolResolver.traitsFor(protocol), + "Example", "AWS_EXAMPLE_API", "example")).render(delegator); + delegator.flushWriters(); + String h = manifest.getFileString(manifest.getFiles().stream() + .filter(p -> p.toString().endsWith("DoThingRequest.h")).findFirst().orElseThrow()).orElseThrow(); + assertFalse(h.contains("GetChecksumAlgorithmName"), h); + assertFalse(h.contains("RequestChecksumRequired"), h); + } + // --- @requestCompression --- /** From ee1ac413f232b24fdd411c2fe289db523b14438d Mon Sep 17 00:00:00 2001 From: sbaluja Date: Thu, 13 Aug 2026 21:51:18 -0400 Subject: [PATCH 16/19] Fix includeTests generation --- tools/scripts/codegen/legacy_c2j_cpp_gen.py | 7 +++---- tools/scripts/run_code_generation.py | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/tools/scripts/codegen/legacy_c2j_cpp_gen.py b/tools/scripts/codegen/legacy_c2j_cpp_gen.py index 0a9d765329d1..bb5bccf518b5 100644 --- a/tools/scripts/codegen/legacy_c2j_cpp_gen.py +++ b/tools/scripts/codegen/legacy_c2j_cpp_gen.py @@ -17,7 +17,6 @@ from concurrent.futures import ProcessPoolExecutor, wait, FIRST_COMPLETED, ALL_COMPLETED from pathlib import Path -from codegen.include_tests_util import IncludeTestsUtil from codegen.model_utils import ServiceModel from codegen.smithy_cpp_gen import bdd_endpoint_services @@ -272,9 +271,9 @@ def _generate_single_service(self, if model_files.endpoint_rule_set and model_files.endpoint_tests: self._generate_client_endpoint_tests(service_name, model_files, f"{output_dir}/tests", tmp_dir) - IncludeTestsUtil.generate(service_name, - f"{output_dir}/src/aws-cpp-sdk-{service_name}", - f"{output_dir}/tests/{service_name}-gen-tests") + # NOTE: the include test is generated later (in run_code_generation.main), after the + # Smithy pass writes model/*.h. Generating it here would miss those headers for + # --use-smithy-models services, whose model generation C2J skips. return service_name, status diff --git a/tools/scripts/run_code_generation.py b/tools/scripts/run_code_generation.py index f3fffe6fa95c..aed9db20ffa3 100644 --- a/tools/scripts/run_code_generation.py +++ b/tools/scripts/run_code_generation.py @@ -10,6 +10,7 @@ from pathlib import Path from codegen.legacy_c2j_cpp_gen import LegacyC2jCppGen, CLIENT_MODEL_FILE_LOCATION, ENDPOINT_RULES_LOCATION +from codegen.include_tests_util import IncludeTestsUtil from codegen.model_utils import ModelUtils from codegen.protocol_tests_gen import ProtocolTestsGen from codegen.smoke_tests_gen import SmokeTestsGen @@ -221,6 +222,19 @@ def main(): print("ERROR: Failed to generate Smithy code!") return -1 + # Generate include tests AFTER both the C2J and Smithy passes, so the client's include/ tree + # is complete. IncludeTestsUtil scans that tree on disk; C2J skips model generation for + # --use-smithy-models services (their model/*.h are written by the Smithy pass above), so + # generating include tests during the C2J pass would omit every model header. + if clients_to_build: + for client in clients_to_build: + service_client_dir = f"{args['output_location']}/src/aws-cpp-sdk-{client}" + test_output_dir = f"{args['output_location']}/tests/{client}-gen-tests" + # The gen-tests dir exists only for services that got endpoint tests generated, which + # is the same condition under which the include test was previously produced. + if os.path.isdir(service_client_dir) and os.path.isdir(test_output_dir): + IncludeTestsUtil.generate(client, service_client_dir, test_output_dir) + if args["generate_smoke_tests"] and clients_to_build: smoke_tests_gen = SmokeTestsGen(args["debug"]) if smoke_tests_gen.generate(clients_to_build) != 0: From 11b3396e7f623462655b9165861fbb61fdf6f05d Mon Sep 17 00:00:00 2001 From: sbaluja Date: Thu, 13 Aug 2026 22:30:32 -0400 Subject: [PATCH 17/19] updated include tests --- .../MigrationHubIncludeTests.cpp | 11 ++ .../AccessAnalyzerIncludeTests.cpp | 15 ++ .../AccountAccessIncludeTests.cpp | 6 + .../account-gen-tests/AccountIncludeTests.cpp | 5 + .../tests/acm-gen-tests/ACMIncludeTests.cpp | 10 + .../acm-pca-gen-tests/ACMPCAIncludeTests.cpp | 7 + .../AgentRegistryControlIncludeTests.cpp | 6 + .../AgentRegistryIncludeTests.cpp | 5 + .../aiops-gen-tests/AIOpsIncludeTests.cpp | 5 + .../PrometheusServiceIncludeTests.cpp | 8 + .../amplify-gen-tests/AmplifyIncludeTests.cpp | 8 + .../AmplifyBackendIncludeTests.cpp | 3 + .../AmplifyUIBuilderIncludeTests.cpp | 11 ++ .../APIGatewayIncludeTests.cpp | 16 ++ .../ApiGatewayManagementApiIncludeTests.cpp | 3 + .../ApiGatewayV2IncludeTests.cpp | 5 + .../AppConfigIncludeTests.cpp | 15 ++ .../AppConfigDataIncludeTests.cpp | 3 + .../AppFabricIncludeTests.cpp | 8 + .../appflow-gen-tests/AppflowIncludeTests.cpp | 9 + .../AppIntegrationsServiceIncludeTests.cpp | 10 + .../ApplicationAutoScalingIncludeTests.cpp | 8 + .../ApplicationInsightsIncludeTests.cpp | 11 ++ .../ApplicationSignalsIncludeTests.cpp | 14 ++ .../ApplicationCostProfilerIncludeTests.cpp | 5 + .../appmesh-gen-tests/AppMeshIncludeTests.cpp | 12 ++ .../AppRunnerIncludeTests.cpp | 13 ++ .../AppStreamIncludeTests.cpp | 8 + .../appsync-gen-tests/AppSyncIncludeTests.cpp | 16 ++ .../ARCRegionswitchIncludeTests.cpp | 12 ++ .../ARCZonalShiftIncludeTests.cpp | 7 + .../ArtifactIncludeTests.cpp | 9 + .../athena-gen-tests/AthenaIncludeTests.cpp | 19 ++ .../AuditManagerIncludeTests.cpp | 20 ++ .../AutoScalingIncludeTests.cpp | 17 ++ .../AutoScalingPlansIncludeTests.cpp | 3 + .../TransferIncludeTests.cpp | 17 ++ .../tests/b2bi-gen-tests/B2BIIncludeTests.cpp | 8 + .../BackupGatewayIncludeTests.cpp | 7 + .../backup-gen-tests/BackupIncludeTests.cpp | 36 ++++ .../BackupSearchIncludeTests.cpp | 8 + .../batch-gen-tests/BatchIncludeTests.cpp | 14 ++ .../BCMDashboardsIncludeTests.cpp | 6 + .../BCMDataExportsIncludeTests.cpp | 7 + .../BCMPricingCalculatorIncludeTests.cpp | 14 ++ .../BCMRecommendedActionsIncludeTests.cpp | 5 + .../BedrockAgentIncludeTests.cpp | 18 ++ .../BedrockAgentRuntimeIncludeTests.cpp | 12 ++ .../BedrockAgentCoreControlIncludeTests.cpp | 42 +++++ .../BedrockAgentCoreIncludeTests.cpp | 15 ++ .../BedrockDataAutomationIncludeTests.cpp | 9 + ...drockDataAutomationRuntimeIncludeTests.cpp | 3 + .../bedrock-gen-tests/BedrockIncludeTests.cpp | 23 +++ .../BedrockRuntimeIncludeTests.cpp | 5 + .../billing-gen-tests/BillingIncludeTests.cpp | 8 + .../BillingConductorIncludeTests.cpp | 15 ++ .../braket-gen-tests/BraketIncludeTests.cpp | 8 + .../budgets-gen-tests/BudgetsIncludeTests.cpp | 12 ++ .../ce-gen-tests/CostExplorerIncludeTests.cpp | 19 ++ .../chatbot-gen-tests/ChatbotIncludeTests.cpp | 13 ++ .../chime-gen-tests/ChimeIncludeTests.cpp | 12 ++ .../ChimeSDKIdentityIncludeTests.cpp | 9 + .../ChimeSDKMediaPipelinesIncludeTests.cpp | 8 + .../ChimeSDKMeetingsIncludeTests.cpp | 5 + .../ChimeSDKMessagingIncludeTests.cpp | 15 ++ .../ChimeSDKVoiceIncludeTests.cpp | 13 ++ .../CleanRoomsIncludeTests.cpp | 27 +++ .../CleanRoomsMLIncludeTests.cpp | 20 ++ .../cloud9-gen-tests/Cloud9IncludeTests.cpp | 6 + .../CloudControlApiIncludeTests.cpp | 6 + .../CloudDirectoryIncludeTests.cpp | 23 +++ .../CloudFormationIncludeTests.cpp | 28 +++ .../CloudFrontIncludeTests.cpp | 21 +++ .../CloudFrontKeyValueStoreIncludeTests.cpp | 5 + .../CloudHSMIncludeTests.cpp | 3 + .../CloudHSMV2IncludeTests.cpp | 7 + .../CloudSearchIncludeTests.cpp | 3 + .../CloudSearchDomainIncludeTests.cpp | 3 + .../CloudTrailDataIncludeTests.cpp | 3 + .../CloudTrailIncludeTests.cpp | 16 ++ .../CodeArtifactIncludeTests.cpp | 14 ++ .../CodeBuildIncludeTests.cpp | 20 ++ .../CodeCatalystIncludeTests.cpp | 14 ++ .../CodeCommitIncludeTests.cpp | 18 ++ .../CodeConnectionsIncludeTests.cpp | 8 + .../CodeDeployIncludeTests.cpp | 9 + .../CodeGuruReviewerIncludeTests.cpp | 8 + .../CodeGuruSecurityIncludeTests.cpp | 7 + .../CodeGuruProfilerIncludeTests.cpp | 8 + .../CodePipelineIncludeTests.cpp | 12 ++ .../CodeStarconnectionsIncludeTests.cpp | 8 + .../CodeStarNotificationsIncludeTests.cpp | 7 + .../CognitoIdentityIncludeTests.cpp | 5 + .../CognitoIdentityProviderIncludeTests.cpp | 13 ++ .../CognitoSyncIncludeTests.cpp | 3 + .../ComprehendIncludeTests.cpp | 21 +++ .../ComprehendMedicalIncludeTests.cpp | 3 + ...ComputeOptimizerAutomationIncludeTests.cpp | 13 ++ .../ComputeOptimizerIncludeTests.cpp | 9 + .../ConfigServiceIncludeTests.cpp | 46 +++++ .../ConnectContactLensIncludeTests.cpp | 5 + .../connect-gen-tests/ConnectIncludeTests.cpp | 93 ++++++++++ .../ConnectCampaignsIncludeTests.cpp | 5 + .../ConnectCampaignsV2IncludeTests.cpp | 6 + .../ConnectCasesIncludeTests.cpp | 16 ++ .../ConnectHealthIncludeTests.cpp | 6 + .../ConnectParticipantIncludeTests.cpp | 5 + .../ControlCatalogIncludeTests.cpp | 9 + .../ControlTowerIncludeTests.cpp | 10 + .../CostOptimizationHubIncludeTests.cpp | 8 + .../CostandUsageReportServiceIncludeTests.cpp | 5 + .../CustomerProfilesIncludeTests.cpp | 17 ++ .../GlueDataBrewIncludeTests.cpp | 12 ++ .../DataExchangeIncludeTests.cpp | 11 ++ .../DataPipelineIncludeTests.cpp | 7 + .../DataSyncIncludeTests.cpp | 9 + .../DataZoneIncludeTests.cpp | 44 +++++ .../tests/dax-gen-tests/DAXIncludeTests.cpp | 3 + .../DeadlineIncludeTests.cpp | 34 ++++ .../DetectiveIncludeTests.cpp | 9 + .../DeviceFarmIncludeTests.cpp | 22 +++ .../DevOpsAgentIncludeTests.cpp | 16 ++ .../DevOpsGuruIncludeTests.cpp | 18 ++ .../DirectConnectIncludeTests.cpp | 3 + .../DirectoryServiceDataIncludeTests.cpp | 10 + ...pplicationDiscoveryServiceIncludeTests.cpp | 10 + .../tests/dlm-gen-tests/DLMIncludeTests.cpp | 3 + .../DatabaseMigrationServiceIncludeTests.cpp | 46 +++++ .../DocDBElasticIncludeTests.cpp | 7 + .../docdb-gen-tests/DocDBIncludeTests.cpp | 17 ++ .../tests/drs-gen-tests/DrsIncludeTests.cpp | 15 ++ .../DirectoryServiceIncludeTests.cpp | 19 ++ .../tests/dsql-gen-tests/DSQLIncludeTests.cpp | 6 + .../DynamoDBIncludeTests.cpp | 10 + .../DynamoDBStreamsIncludeTests.cpp | 3 + .../tests/ebs-gen-tests/EBSIncludeTests.cpp | 6 + .../tests/ec2-gen-tests/EC2IncludeTests.cpp | 174 ++++++++++++++++++ .../EC2InstanceConnectIncludeTests.cpp | 3 + .../tests/ecr-gen-tests/ECRIncludeTests.cpp | 11 ++ .../ECRPublicIncludeTests.cpp | 8 + .../tests/ecs-gen-tests/ECSIncludeTests.cpp | 13 ++ .../EKSAuthIncludeTests.cpp | 3 + .../tests/eks-gen-tests/EKSIncludeTests.cpp | 19 ++ .../ElastiCacheIncludeTests.cpp | 23 +++ .../ElasticBeanstalkIncludeTests.cpp | 8 + .../EFSIncludeTests.cpp | 9 + .../ElasticLoadBalancingIncludeTests.cpp | 5 + .../ElasticLoadBalancingv2IncludeTests.cpp | 13 ++ .../EMRIncludeTests.cpp | 17 ++ .../ElementalInferenceIncludeTests.cpp | 7 + .../tests/email-gen-tests/SESIncludeTests.cpp | 6 + .../EMRContainersIncludeTests.cpp | 9 + .../EMRServerlessIncludeTests.cpp | 8 + .../EntityResolutionIncludeTests.cpp | 11 ++ .../ElasticsearchServiceIncludeTests.cpp | 16 ++ .../EventBridgeIncludeTests.cpp | 3 + .../CloudWatchEventsIncludeTests.cpp | 3 + .../tests/evs-gen-tests/EVSIncludeTests.cpp | 9 + .../FinSpaceDataIncludeTests.cpp | 3 + .../FinspaceIncludeTests.cpp | 10 + .../FirehoseIncludeTests.cpp | 3 + .../tests/fis-gen-tests/FISIncludeTests.cpp | 10 + .../tests/fms-gen-tests/FMSIncludeTests.cpp | 12 ++ .../ForecastServiceIncludeTests.cpp | 18 ++ .../ForecastQueryServiceIncludeTests.cpp | 3 + .../FraudDetectorIncludeTests.cpp | 20 ++ .../FreeTierIncludeTests.cpp | 6 + .../tests/fsx-gen-tests/FSxIncludeTests.cpp | 15 ++ .../GameLiftIncludeTests.cpp | 31 ++++ .../GameLiftStreamsIncludeTests.cpp | 9 + .../GeoMapsIncludeTests.cpp | 3 + .../GeoPlacesIncludeTests.cpp | 3 + .../GeoRoutesIncludeTests.cpp | 3 + .../glacier-gen-tests/GlacierIncludeTests.cpp | 8 + .../GlobalAcceleratorIncludeTests.cpp | 15 ++ .../tests/glue-gen-tests/GlueIncludeTests.cpp | 56 ++++++ .../ManagedGrafanaIncludeTests.cpp | 9 + .../GreengrassIncludeTests.cpp | 3 + .../GreengrassV2IncludeTests.cpp | 11 ++ .../GroundStationIncludeTests.cpp | 14 ++ .../GuardDutyIncludeTests.cpp | 21 +++ .../health-gen-tests/HealthIncludeTests.cpp | 11 ++ .../HealthLakeIncludeTests.cpp | 10 + .../tests/iam-gen-tests/IAMIncludeTests.cpp | 38 ++++ .../IdentityStoreIncludeTests.cpp | 8 + .../ImagebuilderIncludeTests.cpp | 25 +++ .../ImportExportIncludeTests.cpp | 2 + .../InspectorIncludeTests.cpp | 14 ++ .../InspectorscanIncludeTests.cpp | 3 + .../Inspector2IncludeTests.cpp | 22 +++ .../InterconnectIncludeTests.cpp | 7 + .../InternetMonitorIncludeTests.cpp | 8 + .../InvoicingIncludeTests.cpp | 7 + .../IoTDataPlaneIncludeTests.cpp | 6 + .../tests/iot-gen-tests/IoTIncludeTests.cpp | 66 +++++++ .../IoTJobsDataPlaneIncludeTests.cpp | 3 + .../IoTManagedIntegrationsIncludeTests.cpp | 21 +++ .../IoTDeviceAdvisorIncludeTests.cpp | 6 + .../IoTFleetWiseIncludeTests.cpp | 18 ++ .../IoTSecureTunnelingIncludeTests.cpp | 5 + .../IoTSiteWiseIncludeTests.cpp | 48 +++++ .../IoTThingsGraphIncludeTests.cpp | 3 + .../IoTTwinMakerIncludeTests.cpp | 16 ++ .../IoTWirelessIncludeTests.cpp | 14 ++ .../tests/ivs-gen-tests/IVSIncludeTests.cpp | 12 ++ .../IvsrealtimeIncludeTests.cpp | 14 ++ .../ivschat-gen-tests/IvschatIncludeTests.cpp | 6 + .../kafka-gen-tests/KafkaIncludeTests.cpp | 18 ++ .../KafkaConnectIncludeTests.cpp | 8 + .../kendra-gen-tests/KendraIncludeTests.cpp | 16 ++ .../KendraRankingIncludeTests.cpp | 5 + .../KeyspacesIncludeTests.cpp | 8 + .../KeyspacesStreamsIncludeTests.cpp | 6 + .../kinesis-gen-tests/KinesisIncludeTests.cpp | 6 + .../KinesisVideoArchivedMediaIncludeTests.cpp | 6 + .../KinesisVideoMediaIncludeTests.cpp | 3 + ...esisVideoSignalingChannelsIncludeTests.cpp | 3 + .../KinesisVideoWebRTCStorageIncludeTests.cpp | 3 + .../KinesisAnalyticsIncludeTests.cpp | 3 + .../KinesisAnalyticsV2IncludeTests.cpp | 8 + .../KinesisVideoIncludeTests.cpp | 8 + .../tests/kms-gen-tests/KMSIncludeTests.cpp | 12 ++ .../LakeFormationIncludeTests.cpp | 17 ++ .../LambdaCoreIncludeTests.cpp | 5 + .../lambda-gen-tests/LambdaIncludeTests.cpp | 20 ++ .../LambdaMicrovmsIncludeTests.cpp | 10 + .../LaunchWizardIncludeTests.cpp | 9 + .../LexRuntimeServiceIncludeTests.cpp | 3 + .../LexModelBuildingServiceIncludeTests.cpp | 3 + .../LexModelsV2IncludeTests.cpp | 34 ++++ .../LexRuntimeV2IncludeTests.cpp | 3 + .../LicenseManagerIncludeTests.cpp | 3 + ...eManagerLinuxSubscriptionsIncludeTests.cpp | 7 + ...seManagerUserSubscriptionsIncludeTests.cpp | 9 + .../LightsailIncludeTests.cpp | 3 + .../LocationServiceIncludeTests.cpp | 16 ++ .../CloudWatchLogsIncludeTests.cpp | 22 +++ .../LookoutEquipmentIncludeTests.cpp | 15 ++ .../MainframeModernizationIncludeTests.cpp | 14 ++ .../MachineLearningIncludeTests.cpp | 8 + .../macie2-gen-tests/Macie2IncludeTests.cpp | 21 +++ .../MailManagerIncludeTests.cpp | 16 ++ .../ManagedBlockchainIncludeTests.cpp | 11 ++ .../ManagedBlockchainQueryIncludeTests.cpp | 9 + .../AgreementServiceIncludeTests.cpp | 12 ++ .../MarketplaceCatalogIncludeTests.cpp | 6 + .../MarketplaceDeploymentIncludeTests.cpp | 3 + .../MarketplaceDiscoveryIncludeTests.cpp | 9 + ...ketplaceEntitlementServiceIncludeTests.cpp | 5 + .../MarketplaceReportingIncludeTests.cpp | 3 + ...rketplaceCommerceAnalyticsIncludeTests.cpp | 3 + .../MediaConnectIncludeTests.cpp | 14 ++ .../MediaConvertIncludeTests.cpp | 10 + .../MediaLiveIncludeTests.cpp | 27 +++ .../MediaPackageIncludeTests.cpp | 7 + .../MediaPackageVodIncludeTests.cpp | 7 + .../Mediapackagev2IncludeTests.cpp | 8 + .../MediaStoreDataIncludeTests.cpp | 5 + .../MediaStoreIncludeTests.cpp | 5 + .../MediaTailorIncludeTests.cpp | 13 ++ .../MedicalImagingIncludeTests.cpp | 8 + .../MemoryDBIncludeTests.cpp | 17 ++ .../MarketplaceMeteringIncludeTests.cpp | 3 + .../tests/mgn-gen-tests/MgnIncludeTests.cpp | 33 ++++ ...MigrationHubRefactorSpacesIncludeTests.cpp | 9 + .../MigrationHubConfigIncludeTests.cpp | 5 + .../MigrationHubOrchestratorIncludeTests.cpp | 11 ++ ...HubStrategyRecommendationsIncludeTests.cpp | 10 + .../CloudWatchIncludeTests.cpp | 14 ++ .../tests/mpa-gen-tests/MPAIncludeTests.cpp | 10 + .../tests/mq-gen-tests/MQIncludeTests.cpp | 6 + .../MTurkIncludeTests.cpp | 14 ++ .../tests/mwaa-gen-tests/MWAAIncludeTests.cpp | 5 + .../MWAAServerlessIncludeTests.cpp | 8 + .../neptune-gen-tests/NeptuneIncludeTests.cpp | 20 ++ .../NeptuneGraphIncludeTests.cpp | 9 + .../NeptunedataIncludeTests.cpp | 3 + .../NetworkFirewallIncludeTests.cpp | 18 ++ .../NetworkFlowMonitorIncludeTests.cpp | 9 + .../NetworkManagerIncludeTests.cpp | 28 +++ .../NetworkMonitorIncludeTests.cpp | 5 + .../NotificationsIncludeTests.cpp | 15 ++ .../NotificationsContactsIncludeTests.cpp | 5 + .../NovaActIncludeTests.cpp | 8 + .../tests/oam-gen-tests/OAMIncludeTests.cpp | 7 + .../ObservabilityAdminIncludeTests.cpp | 11 ++ .../tests/odb-gen-tests/OdbIncludeTests.cpp | 24 +++ .../omics-gen-tests/OmicsIncludeTests.cpp | 29 +++ .../OpenSearchServiceIncludeTests.cpp | 19 ++ .../OpenSearchServerlessIncludeTests.cpp | 11 ++ .../OrganizationsIncludeTests.cpp | 22 +++ .../tests/osis-gen-tests/OSISIncludeTests.cpp | 7 + .../OutpostsIncludeTests.cpp | 17 ++ .../PartnerCentralAccountIncludeTests.cpp | 7 + .../PartnerCentralBenefitsIncludeTests.cpp | 7 + .../PartnerCentralChannelIncludeTests.cpp | 7 + ...rCentralRevenueMeasurementIncludeTests.cpp | 8 + .../PartnerCentralSellingIncludeTests.cpp | 16 ++ .../PaymentCryptographyDataIncludeTests.cpp | 3 + .../PaymentCryptographyIncludeTests.cpp | 7 + .../PcaConnectorAdIncludeTests.cpp | 9 + .../PcaConnectorScepIncludeTests.cpp | 6 + .../tests/pcs-gen-tests/PCSIncludeTests.cpp | 7 + .../PersonalizeEventsIncludeTests.cpp | 3 + .../PersonalizeIncludeTests.cpp | 20 ++ .../PersonalizeRuntimeIncludeTests.cpp | 3 + .../tests/pi-gen-tests/PIIncludeTests.cpp | 10 + .../PinpointEmailIncludeTests.cpp | 10 + .../PinpointIncludeTests.cpp | 3 + .../PinpointSMSVoiceV2IncludeTests.cpp | 31 ++++ .../pipes-gen-tests/PipesIncludeTests.cpp | 5 + .../polly-gen-tests/PollyIncludeTests.cpp | 5 + .../pricing-gen-tests/PricingIncludeTests.cpp | 8 + .../PricingPlanManagerIncludeTests.cpp | 5 + .../proton-gen-tests/ProtonIncludeTests.cpp | 3 + .../qapps-gen-tests/QAppsIncludeTests.cpp | 6 + .../QBusinessIncludeTests.cpp | 24 +++ .../QConnectIncludeTests.cpp | 26 +++ .../QuickSightIncludeTests.cpp | 53 ++++++ .../tests/ram-gen-tests/RAMIncludeTests.cpp | 18 ++ .../rbin-gen-tests/RecycleBinIncludeTests.cpp | 5 + .../RDSDataServiceIncludeTests.cpp | 3 + .../tests/rds-gen-tests/RDSIncludeTests.cpp | 46 +++++ .../RedshiftDataAPIServiceIncludeTests.cpp | 12 ++ .../RedshiftIncludeTests.cpp | 42 +++++ .../RedshiftServerlessIncludeTests.cpp | 18 ++ .../RekognitionIncludeTests.cpp | 22 +++ .../RepostspaceIncludeTests.cpp | 6 + .../ResilienceHubIncludeTests.cpp | 24 +++ .../Resiliencehubv2IncludeTests.cpp | 25 +++ .../ResourceExplorer2IncludeTests.cpp | 15 ++ .../ResourceGroupsIncludeTests.cpp | 9 + .../ResourceGroupsTaggingAPIIncludeTests.cpp | 9 + .../RolesAnywhereIncludeTests.cpp | 8 + .../route53-gen-tests/Route53IncludeTests.cpp | 10 + .../Route53RecoveryClusterIncludeTests.cpp | 5 + ...ute53RecoveryControlConfigIncludeTests.cpp | 9 + .../Route53RecoveryReadinessIncludeTests.cpp | 14 ++ .../Route53DomainsIncludeTests.cpp | 8 + .../Route53GlobalResolverIncludeTests.cpp | 14 ++ .../Route53ProfilesIncludeTests.cpp | 7 + .../Route53ResolverIncludeTests.cpp | 21 +++ .../RTBFabricIncludeTests.cpp | 9 + .../CloudWatchRUMIncludeTests.cpp | 8 + .../s3-crt-gen-tests/S3CrtIncludeTests.cpp | 9 + .../tests/s3-gen-tests/S3IncludeTests.cpp | 9 + .../S3ControlIncludeTests.cpp | 16 ++ .../s3files-gen-tests/S3FilesIncludeTests.cpp | 8 + .../S3OutpostsIncludeTests.cpp | 7 + .../S3TablesIncludeTests.cpp | 7 + .../S3VectorsIncludeTests.cpp | 8 + .../AugmentedAIRuntimeIncludeTests.cpp | 5 + .../SagemakerEdgeManagerIncludeTests.cpp | 3 + ...geMakerFeatureStoreRuntimeIncludeTests.cpp | 5 + .../SageMakerIncludeTests.cpp | 95 ++++++++++ .../SageMakerGeospatialIncludeTests.cpp | 8 + .../SageMakerMetricsIncludeTests.cpp | 3 + .../SageMakerRuntimeIncludeTests.cpp | 3 + .../SageMakerRuntimeHTTP2IncludeTests.cpp | 3 + .../SagemakerJobRuntimeIncludeTests.cpp | 3 + .../SavingsPlansIncludeTests.cpp | 3 + .../SchedulerIncludeTests.cpp | 6 + .../schemas-gen-tests/SchemasIncludeTests.cpp | 9 + .../sdb-gen-tests/SimpleDBIncludeTests.cpp | 2 + .../SecretsManagerIncludeTests.cpp | 7 + .../SecurityIRIncludeTests.cpp | 9 + .../SecurityAgentIncludeTests.cpp | 26 +++ .../SecurityHubIncludeTests.cpp | 29 +++ .../SecurityLakeIncludeTests.cpp | 8 + ...rlessApplicationRepositoryIncludeTests.cpp | 7 + .../ServiceQuotasIncludeTests.cpp | 10 + .../AppRegistryIncludeTests.cpp | 9 + .../ServiceCatalogIncludeTests.cpp | 23 +++ .../ServiceDiscoveryIncludeTests.cpp | 9 + .../sesv2-gen-tests/SESV2IncludeTests.cpp | 23 +++ .../shield-gen-tests/ShieldIncludeTests.cpp | 8 + .../SignerDataIncludeTests.cpp | 3 + .../signer-gen-tests/SignerIncludeTests.cpp | 7 + .../signin-gen-tests/SigninIncludeTests.cpp | 5 + .../SimpleDBv2IncludeTests.cpp | 5 + .../PinpointSMSVoiceIncludeTests.cpp | 3 + .../SnowDeviceManagementIncludeTests.cpp | 8 + .../SnowballIncludeTests.cpp | 11 ++ .../tests/sns-gen-tests/SNSIncludeTests.cpp | 12 ++ .../SocialMessagingIncludeTests.cpp | 9 + .../tests/sqs-gen-tests/SQSIncludeTests.cpp | 6 + .../SSMContactsIncludeTests.cpp | 15 ++ .../tests/ssm-gen-tests/SSMIncludeTests.cpp | 56 ++++++ .../SSMGuiConnectIncludeTests.cpp | 3 + .../SSMIncidentsIncludeTests.cpp | 11 ++ .../SSMQuickSetupIncludeTests.cpp | 6 + .../ssm-sap-gen-tests/SsmSapIncludeTests.cpp | 13 ++ .../SSOAdminIncludeTests.cpp | 25 +++ .../tests/sso-gen-tests/SSOIncludeTests.cpp | 6 + .../SSOOIDCIncludeTests.cpp | 3 + .../states-gen-tests/SFNIncludeTests.cpp | 9 + .../StorageGatewayIncludeTests.cpp | 16 ++ .../tests/sts-gen-tests/STSIncludeTests.cpp | 3 + .../SupplyChainIncludeTests.cpp | 10 + .../SupportAppIncludeTests.cpp | 6 + .../support-gen-tests/SupportIncludeTests.cpp | 6 + .../SupportAuthZIncludeTests.cpp | 7 + .../SustainabilityIncludeTests.cpp | 8 + .../tests/swf-gen-tests/SWFIncludeTests.cpp | 11 ++ .../SyntheticsIncludeTests.cpp | 11 ++ .../TaxSettingsIncludeTests.cpp | 7 + .../TextractIncludeTests.cpp | 6 + .../TimestreamInfluxDBIncludeTests.cpp | 9 + .../TimestreamQueryIncludeTests.cpp | 7 + .../TimestreamWriteIncludeTests.cpp | 7 + .../tests/tnb-gen-tests/TnbIncludeTests.cpp | 9 + .../TranscribeServiceIncludeTests.cpp | 13 ++ ...TranscribeStreamingServiceIncludeTests.cpp | 3 + .../TranslateIncludeTests.cpp | 8 + .../TrustedAdvisorIncludeTests.cpp | 11 ++ .../tests/uxc-gen-tests/UxcIncludeTests.cpp | 5 + .../VerifiedPermissionsIncludeTests.cpp | 9 + .../VoiceIDIncludeTests.cpp | 10 + .../VPCLatticeIncludeTests.cpp | 19 ++ .../tests/waf-gen-tests/WAFIncludeTests.cpp | 3 + .../WAFRegionalIncludeTests.cpp | 3 + .../wafv2-gen-tests/WAFV2IncludeTests.cpp | 3 + .../WellArchitectedIncludeTests.cpp | 29 +++ .../wickr-gen-tests/WickrIncludeTests.cpp | 12 ++ .../ConnectWisdomServiceIncludeTests.cpp | 13 ++ .../WorkDocsIncludeTests.cpp | 14 ++ .../WorkMailIncludeTests.cpp | 19 ++ .../WorkMailMessageFlowIncludeTests.cpp | 3 + .../WorkSpacesIncludeTests.cpp | 10 + .../WorkspacesInstancesIncludeTests.cpp | 7 + .../WorkSpacesThinIncludeTestIncludeTests.cpp | 7 + .../WorkSpacesWebIncludeTests.cpp | 16 ++ .../tests/xray-gen-tests/XRayIncludeTests.cpp | 16 ++ 433 files changed, 5267 insertions(+) diff --git a/generated/tests/AWSMigrationHub-gen-tests/MigrationHubIncludeTests.cpp b/generated/tests/AWSMigrationHub-gen-tests/MigrationHubIncludeTests.cpp index cff312aeae91..63611c260fdd 100644 --- a/generated/tests/AWSMigrationHub-gen-tests/MigrationHubIncludeTests.cpp +++ b/generated/tests/AWSMigrationHub-gen-tests/MigrationHubIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -39,18 +43,25 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/accessanalyzer-gen-tests/AccessAnalyzerIncludeTests.cpp b/generated/tests/accessanalyzer-gen-tests/AccessAnalyzerIncludeTests.cpp index e82b8da63ee7..fbad52d07e92 100644 --- a/generated/tests/accessanalyzer-gen-tests/AccessAnalyzerIncludeTests.cpp +++ b/generated/tests/accessanalyzer-gen-tests/AccessAnalyzerIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -91,10 +95,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -120,20 +126,28 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -204,6 +218,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/account-access-gen-tests/AccountAccessIncludeTests.cpp b/generated/tests/account-access-gen-tests/AccountAccessIncludeTests.cpp index 77e2f4889c94..89494dd74a77 100644 --- a/generated/tests/account-access-gen-tests/AccountAccessIncludeTests.cpp +++ b/generated/tests/account-access-gen-tests/AccountAccessIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -39,8 +43,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/account-gen-tests/AccountIncludeTests.cpp b/generated/tests/account-gen-tests/AccountIncludeTests.cpp index f92836720e80..db7cf4464bf7 100644 --- a/generated/tests/account-gen-tests/AccountIncludeTests.cpp +++ b/generated/tests/account-gen-tests/AccountIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -40,6 +44,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/acm-gen-tests/ACMIncludeTests.cpp b/generated/tests/acm-gen-tests/ACMIncludeTests.cpp index e5201ebc3dc5..6996c86f93ab 100644 --- a/generated/tests/acm-gen-tests/ACMIncludeTests.cpp +++ b/generated/tests/acm-gen-tests/ACMIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -97,14 +101,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -133,6 +142,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/acm-pca-gen-tests/ACMPCAIncludeTests.cpp b/generated/tests/acm-pca-gen-tests/ACMPCAIncludeTests.cpp index 083f9c3e34dd..73eb31f34ee4 100644 --- a/generated/tests/acm-pca-gen-tests/ACMPCAIncludeTests.cpp +++ b/generated/tests/acm-pca-gen-tests/ACMPCAIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -64,10 +68,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/agent-registry-control-gen-tests/AgentRegistryControlIncludeTests.cpp b/generated/tests/agent-registry-control-gen-tests/AgentRegistryControlIncludeTests.cpp index 2025f3d9071b..77194c7fd176 100644 --- a/generated/tests/agent-registry-control-gen-tests/AgentRegistryControlIncludeTests.cpp +++ b/generated/tests/agent-registry-control-gen-tests/AgentRegistryControlIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -44,8 +48,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/agent-registry-gen-tests/AgentRegistryIncludeTests.cpp b/generated/tests/agent-registry-gen-tests/AgentRegistryIncludeTests.cpp index 6852266c7f1a..a12d08eba02e 100644 --- a/generated/tests/agent-registry-gen-tests/AgentRegistryIncludeTests.cpp +++ b/generated/tests/agent-registry-gen-tests/AgentRegistryIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -26,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/aiops-gen-tests/AIOpsIncludeTests.cpp b/generated/tests/aiops-gen-tests/AIOpsIncludeTests.cpp index 18be81e7d090..c654fdd9d2df 100644 --- a/generated/tests/aiops-gen-tests/AIOpsIncludeTests.cpp +++ b/generated/tests/aiops-gen-tests/AIOpsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -26,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/amp-gen-tests/PrometheusServiceIncludeTests.cpp b/generated/tests/amp-gen-tests/PrometheusServiceIncludeTests.cpp index f720c00cdbe0..52e564141e1c 100644 --- a/generated/tests/amp-gen-tests/PrometheusServiceIncludeTests.cpp +++ b/generated/tests/amp-gen-tests/PrometheusServiceIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -80,14 +84,18 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/amplify-gen-tests/AmplifyIncludeTests.cpp b/generated/tests/amplify-gen-tests/AmplifyIncludeTests.cpp index 0fb6848756de..31c643efb4ba 100644 --- a/generated/tests/amplify-gen-tests/AmplifyIncludeTests.cpp +++ b/generated/tests/amplify-gen-tests/AmplifyIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -73,16 +77,20 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/amplifybackend-gen-tests/AmplifyBackendIncludeTests.cpp b/generated/tests/amplifybackend-gen-tests/AmplifyBackendIncludeTests.cpp index ad7f282ac11d..8dea788dd5a1 100644 --- a/generated/tests/amplifybackend-gen-tests/AmplifyBackendIncludeTests.cpp +++ b/generated/tests/amplifybackend-gen-tests/AmplifyBackendIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/amplifyuibuilder-gen-tests/AmplifyUIBuilderIncludeTests.cpp b/generated/tests/amplifyuibuilder-gen-tests/AmplifyUIBuilderIncludeTests.cpp index f22f130ccf51..9eda7804e809 100644 --- a/generated/tests/amplifyuibuilder-gen-tests/AmplifyUIBuilderIncludeTests.cpp +++ b/generated/tests/amplifyuibuilder-gen-tests/AmplifyUIBuilderIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -57,10 +61,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -100,14 +107,18 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/apigateway-gen-tests/APIGatewayIncludeTests.cpp b/generated/tests/apigateway-gen-tests/APIGatewayIncludeTests.cpp index 85cf71fdc84d..2613f7d79005 100644 --- a/generated/tests/apigateway-gen-tests/APIGatewayIncludeTests.cpp +++ b/generated/tests/apigateway-gen-tests/APIGatewayIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -105,6 +109,7 @@ #include #include #include +#include #include #include #include @@ -113,14 +118,17 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -135,6 +143,7 @@ #include #include #include +#include #include #include #include @@ -155,6 +164,7 @@ #include #include #include +#include #include #include #include @@ -163,10 +173,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -181,18 +193,22 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/apigatewaymanagementapi-gen-tests/ApiGatewayManagementApiIncludeTests.cpp b/generated/tests/apigatewaymanagementapi-gen-tests/ApiGatewayManagementApiIncludeTests.cpp index c991f8a93899..53fc728b5bfa 100644 --- a/generated/tests/apigatewaymanagementapi-gen-tests/ApiGatewayManagementApiIncludeTests.cpp +++ b/generated/tests/apigatewaymanagementapi-gen-tests/ApiGatewayManagementApiIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/apigatewayv2-gen-tests/ApiGatewayV2IncludeTests.cpp b/generated/tests/apigatewayv2-gen-tests/ApiGatewayV2IncludeTests.cpp index 509241d36e41..ec8f87f58b08 100644 --- a/generated/tests/apigatewayv2-gen-tests/ApiGatewayV2IncludeTests.cpp +++ b/generated/tests/apigatewayv2-gen-tests/ApiGatewayV2IncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -179,6 +183,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/appconfig-gen-tests/AppConfigIncludeTests.cpp b/generated/tests/appconfig-gen-tests/AppConfigIncludeTests.cpp index dc2d567c3b99..a7d3a4f4d50e 100644 --- a/generated/tests/appconfig-gen-tests/AppConfigIncludeTests.cpp +++ b/generated/tests/appconfig-gen-tests/AppConfigIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -96,26 +100,37 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/appconfigdata-gen-tests/AppConfigDataIncludeTests.cpp b/generated/tests/appconfigdata-gen-tests/AppConfigDataIncludeTests.cpp index 9aae7a620110..517a2cded274 100644 --- a/generated/tests/appconfigdata-gen-tests/AppConfigDataIncludeTests.cpp +++ b/generated/tests/appconfigdata-gen-tests/AppConfigDataIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/appfabric-gen-tests/AppFabricIncludeTests.cpp b/generated/tests/appfabric-gen-tests/AppFabricIncludeTests.cpp index db92a7c47c83..c23b0f6dab20 100644 --- a/generated/tests/appfabric-gen-tests/AppFabricIncludeTests.cpp +++ b/generated/tests/appfabric-gen-tests/AppFabricIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -65,12 +69,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/appflow-gen-tests/AppflowIncludeTests.cpp b/generated/tests/appflow-gen-tests/AppflowIncludeTests.cpp index 7823221becaa..e6a9c165e629 100644 --- a/generated/tests/appflow-gen-tests/AppflowIncludeTests.cpp +++ b/generated/tests/appflow-gen-tests/AppflowIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -70,12 +74,15 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include @@ -119,8 +126,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/appintegrations-gen-tests/AppIntegrationsServiceIncludeTests.cpp b/generated/tests/appintegrations-gen-tests/AppIntegrationsServiceIncludeTests.cpp index bbdf2a964e8b..d8dacce45f6b 100644 --- a/generated/tests/appintegrations-gen-tests/AppIntegrationsServiceIncludeTests.cpp +++ b/generated/tests/appintegrations-gen-tests/AppIntegrationsServiceIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -52,16 +56,22 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/application-autoscaling-gen-tests/ApplicationAutoScalingIncludeTests.cpp b/generated/tests/application-autoscaling-gen-tests/ApplicationAutoScalingIncludeTests.cpp index c61c99d87788..36e895fac674 100644 --- a/generated/tests/application-autoscaling-gen-tests/ApplicationAutoScalingIncludeTests.cpp +++ b/generated/tests/application-autoscaling-gen-tests/ApplicationAutoScalingIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -23,12 +27,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/application-insights-gen-tests/ApplicationInsightsIncludeTests.cpp b/generated/tests/application-insights-gen-tests/ApplicationInsightsIncludeTests.cpp index ea16aba4c3c3..579f93d0d47e 100644 --- a/generated/tests/application-insights-gen-tests/ApplicationInsightsIncludeTests.cpp +++ b/generated/tests/application-insights-gen-tests/ApplicationInsightsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -55,20 +59,27 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/application-signals-gen-tests/ApplicationSignalsIncludeTests.cpp b/generated/tests/application-signals-gen-tests/ApplicationSignalsIncludeTests.cpp index 5d9837a0f680..203ec66fc94c 100644 --- a/generated/tests/application-signals-gen-tests/ApplicationSignalsIncludeTests.cpp +++ b/generated/tests/application-signals-gen-tests/ApplicationSignalsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -65,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -84,24 +89,33 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/applicationcostprofiler-gen-tests/ApplicationCostProfilerIncludeTests.cpp b/generated/tests/applicationcostprofiler-gen-tests/ApplicationCostProfilerIncludeTests.cpp index f229a372584a..03c0c751bdea 100644 --- a/generated/tests/applicationcostprofiler-gen-tests/ApplicationCostProfilerIncludeTests.cpp +++ b/generated/tests/applicationcostprofiler-gen-tests/ApplicationCostProfilerIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -20,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/appmesh-gen-tests/AppMeshIncludeTests.cpp b/generated/tests/appmesh-gen-tests/AppMeshIncludeTests.cpp index 479d36fb59d3..2ebc8e4a2f9b 100644 --- a/generated/tests/appmesh-gen-tests/AppMeshIncludeTests.cpp +++ b/generated/tests/appmesh-gen-tests/AppMeshIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -115,20 +119,28 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/apprunner-gen-tests/AppRunnerIncludeTests.cpp b/generated/tests/apprunner-gen-tests/AppRunnerIncludeTests.cpp index 589b183014f0..a60b93cf6338 100644 --- a/generated/tests/apprunner-gen-tests/AppRunnerIncludeTests.cpp +++ b/generated/tests/apprunner-gen-tests/AppRunnerIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -56,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -80,23 +85,31 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include +#include #include #include #include diff --git a/generated/tests/appstream-gen-tests/AppStreamIncludeTests.cpp b/generated/tests/appstream-gen-tests/AppStreamIncludeTests.cpp index 9ffbc3a214dd..776be933e81e 100644 --- a/generated/tests/appstream-gen-tests/AppStreamIncludeTests.cpp +++ b/generated/tests/appstream-gen-tests/AppStreamIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -120,8 +124,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -140,8 +146,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/appsync-gen-tests/AppSyncIncludeTests.cpp b/generated/tests/appsync-gen-tests/AppSyncIncludeTests.cpp index 39d02a6ec418..a26704a53b9c 100644 --- a/generated/tests/appsync-gen-tests/AppSyncIncludeTests.cpp +++ b/generated/tests/appsync-gen-tests/AppSyncIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -167,30 +171,42 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/arc-region-switch-gen-tests/ARCRegionswitchIncludeTests.cpp b/generated/tests/arc-region-switch-gen-tests/ARCRegionswitchIncludeTests.cpp index b74a7372a521..cfa840a7ccc1 100644 --- a/generated/tests/arc-region-switch-gen-tests/ARCRegionswitchIncludeTests.cpp +++ b/generated/tests/arc-region-switch-gen-tests/ARCRegionswitchIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -62,8 +66,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -82,16 +88,22 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/arc-zonal-shift-gen-tests/ARCZonalShiftIncludeTests.cpp b/generated/tests/arc-zonal-shift-gen-tests/ARCZonalShiftIncludeTests.cpp index d40448767272..2398dc77d075 100644 --- a/generated/tests/arc-zonal-shift-gen-tests/ARCZonalShiftIncludeTests.cpp +++ b/generated/tests/arc-zonal-shift-gen-tests/ARCZonalShiftIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -35,10 +39,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/artifact-gen-tests/ArtifactIncludeTests.cpp b/generated/tests/artifact-gen-tests/ArtifactIncludeTests.cpp index 69c279da7619..f2786e9e1739 100644 --- a/generated/tests/artifact-gen-tests/ArtifactIncludeTests.cpp +++ b/generated/tests/artifact-gen-tests/ArtifactIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -45,14 +49,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/athena-gen-tests/AthenaIncludeTests.cpp b/generated/tests/athena-gen-tests/AthenaIncludeTests.cpp index 6b5c5161b4e6..625d62339f64 100644 --- a/generated/tests/athena-gen-tests/AthenaIncludeTests.cpp +++ b/generated/tests/athena-gen-tests/AthenaIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -107,6 +111,7 @@ #include #include #include +#include #include #include #include @@ -127,36 +132,50 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/auditmanager-gen-tests/AuditManagerIncludeTests.cpp b/generated/tests/auditmanager-gen-tests/AuditManagerIncludeTests.cpp index e1e264108c78..7cd997eb7da5 100644 --- a/generated/tests/auditmanager-gen-tests/AuditManagerIncludeTests.cpp +++ b/generated/tests/auditmanager-gen-tests/AuditManagerIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -114,20 +118,25 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include #include @@ -145,26 +154,37 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/autoscaling-gen-tests/AutoScalingIncludeTests.cpp b/generated/tests/autoscaling-gen-tests/AutoScalingIncludeTests.cpp index 0b9e4ad08d93..1e020f1d8b19 100644 --- a/generated/tests/autoscaling-gen-tests/AutoScalingIncludeTests.cpp +++ b/generated/tests/autoscaling-gen-tests/AutoScalingIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -72,42 +76,55 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/autoscaling-plans-gen-tests/AutoScalingPlansIncludeTests.cpp b/generated/tests/autoscaling-plans-gen-tests/AutoScalingPlansIncludeTests.cpp index 40c499954890..7bb4ff6d3f1f 100644 --- a/generated/tests/autoscaling-plans-gen-tests/AutoScalingPlansIncludeTests.cpp +++ b/generated/tests/autoscaling-plans-gen-tests/AutoScalingPlansIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/awstransfer-gen-tests/TransferIncludeTests.cpp b/generated/tests/awstransfer-gen-tests/TransferIncludeTests.cpp index c19fc10fc36a..64608a2be4be 100644 --- a/generated/tests/awstransfer-gen-tests/TransferIncludeTests.cpp +++ b/generated/tests/awstransfer-gen-tests/TransferIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -134,32 +138,45 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/b2bi-gen-tests/B2BIIncludeTests.cpp b/generated/tests/b2bi-gen-tests/B2BIIncludeTests.cpp index 10794bcdd29d..7a411c9d531c 100644 --- a/generated/tests/b2bi-gen-tests/B2BIIncludeTests.cpp +++ b/generated/tests/b2bi-gen-tests/B2BIIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -61,14 +65,18 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/backup-gateway-gen-tests/BackupGatewayIncludeTests.cpp b/generated/tests/backup-gateway-gen-tests/BackupGatewayIncludeTests.cpp index 8834b264f589..80e01a1bfa70 100644 --- a/generated/tests/backup-gateway-gen-tests/BackupGatewayIncludeTests.cpp +++ b/generated/tests/backup-gateway-gen-tests/BackupGatewayIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -45,12 +49,15 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/backup-gen-tests/BackupIncludeTests.cpp b/generated/tests/backup-gen-tests/BackupIncludeTests.cpp index b29dbc8b4c68..f02493d9736b 100644 --- a/generated/tests/backup-gen-tests/BackupIncludeTests.cpp +++ b/generated/tests/backup-gen-tests/BackupIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -171,68 +175,100 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/backupsearch-gen-tests/BackupSearchIncludeTests.cpp b/generated/tests/backupsearch-gen-tests/BackupSearchIncludeTests.cpp index c45129251612..63a68a851852 100644 --- a/generated/tests/backupsearch-gen-tests/BackupSearchIncludeTests.cpp +++ b/generated/tests/backupsearch-gen-tests/BackupSearchIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -27,12 +31,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/batch-gen-tests/BatchIncludeTests.cpp b/generated/tests/batch-gen-tests/BatchIncludeTests.cpp index 52d7c2f4d0c1..fea72c4be862 100644 --- a/generated/tests/batch-gen-tests/BatchIncludeTests.cpp +++ b/generated/tests/batch-gen-tests/BatchIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -69,12 +73,15 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include @@ -83,6 +90,7 @@ #include #include #include +#include #include #include #include @@ -159,17 +167,23 @@ #include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/bcm-dashboards-gen-tests/BCMDashboardsIncludeTests.cpp b/generated/tests/bcm-dashboards-gen-tests/BCMDashboardsIncludeTests.cpp index 48270787d386..302f5e6428a7 100644 --- a/generated/tests/bcm-dashboards-gen-tests/BCMDashboardsIncludeTests.cpp +++ b/generated/tests/bcm-dashboards-gen-tests/BCMDashboardsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -46,8 +50,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/bcm-data-exports-gen-tests/BCMDataExportsIncludeTests.cpp b/generated/tests/bcm-data-exports-gen-tests/BCMDataExportsIncludeTests.cpp index 7cad20a56047..8e8e40c6cf4d 100644 --- a/generated/tests/bcm-data-exports-gen-tests/BCMDataExportsIncludeTests.cpp +++ b/generated/tests/bcm-data-exports-gen-tests/BCMDataExportsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -37,10 +41,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/bcm-pricing-calculator-gen-tests/BCMPricingCalculatorIncludeTests.cpp b/generated/tests/bcm-pricing-calculator-gen-tests/BCMPricingCalculatorIncludeTests.cpp index 3fb040786ca3..33ca43184e9b 100644 --- a/generated/tests/bcm-pricing-calculator-gen-tests/BCMPricingCalculatorIncludeTests.cpp +++ b/generated/tests/bcm-pricing-calculator-gen-tests/BCMPricingCalculatorIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -101,36 +105,46 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/bcm-recommended-actions-gen-tests/BCMRecommendedActionsIncludeTests.cpp b/generated/tests/bcm-recommended-actions-gen-tests/BCMRecommendedActionsIncludeTests.cpp index e9d38e6b4aa3..4471260528f9 100644 --- a/generated/tests/bcm-recommended-actions-gen-tests/BCMRecommendedActionsIncludeTests.cpp +++ b/generated/tests/bcm-recommended-actions-gen-tests/BCMRecommendedActionsIncludeTests.cpp @@ -7,16 +7,21 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/bedrock-agent-gen-tests/BedrockAgentIncludeTests.cpp b/generated/tests/bedrock-agent-gen-tests/BedrockAgentIncludeTests.cpp index edf5efcb31a4..de98d9603b91 100644 --- a/generated/tests/bedrock-agent-gen-tests/BedrockAgentIncludeTests.cpp +++ b/generated/tests/bedrock-agent-gen-tests/BedrockAgentIncludeTests.cpp @@ -9,12 +9,16 @@ #include #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -253,32 +257,46 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/bedrock-agent-runtime-gen-tests/BedrockAgentRuntimeIncludeTests.cpp b/generated/tests/bedrock-agent-runtime-gen-tests/BedrockAgentRuntimeIncludeTests.cpp index 12a6642a1ba5..867666c86eea 100644 --- a/generated/tests/bedrock-agent-runtime-gen-tests/BedrockAgentRuntimeIncludeTests.cpp +++ b/generated/tests/bedrock-agent-runtime-gen-tests/BedrockAgentRuntimeIncludeTests.cpp @@ -9,12 +9,16 @@ #include #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -177,6 +181,7 @@ #include #include #include +#include #include #include #include @@ -265,14 +270,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -354,6 +364,7 @@ #include #include #include +#include #include #include #include @@ -400,6 +411,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/bedrock-agentcore-control-gen-tests/BedrockAgentCoreControlIncludeTests.cpp b/generated/tests/bedrock-agentcore-control-gen-tests/BedrockAgentCoreControlIncludeTests.cpp index 3d6aff9e4342..47b43d59b613 100644 --- a/generated/tests/bedrock-agentcore-control-gen-tests/BedrockAgentCoreControlIncludeTests.cpp +++ b/generated/tests/bedrock-agentcore-control-gen-tests/BedrockAgentCoreControlIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -455,82 +459,120 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/bedrock-agentcore-gen-tests/BedrockAgentCoreIncludeTests.cpp b/generated/tests/bedrock-agentcore-gen-tests/BedrockAgentCoreIncludeTests.cpp index baaa22dcf17c..7e971be09781 100644 --- a/generated/tests/bedrock-agentcore-gen-tests/BedrockAgentCoreIncludeTests.cpp +++ b/generated/tests/bedrock-agentcore-gen-tests/BedrockAgentCoreIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -272,28 +276,38 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -368,6 +382,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/bedrock-data-automation-gen-tests/BedrockDataAutomationIncludeTests.cpp b/generated/tests/bedrock-data-automation-gen-tests/BedrockDataAutomationIncludeTests.cpp index 650c49f7f0c1..3bef2e2c477a 100644 --- a/generated/tests/bedrock-data-automation-gen-tests/BedrockDataAutomationIncludeTests.cpp +++ b/generated/tests/bedrock-data-automation-gen-tests/BedrockDataAutomationIncludeTests.cpp @@ -9,12 +9,16 @@ #include #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -117,14 +121,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/bedrock-data-automation-runtime-gen-tests/BedrockDataAutomationRuntimeIncludeTests.cpp b/generated/tests/bedrock-data-automation-runtime-gen-tests/BedrockDataAutomationRuntimeIncludeTests.cpp index 567e13d14ea9..b665b1281497 100644 --- a/generated/tests/bedrock-data-automation-runtime-gen-tests/BedrockDataAutomationRuntimeIncludeTests.cpp +++ b/generated/tests/bedrock-data-automation-runtime-gen-tests/BedrockDataAutomationRuntimeIncludeTests.cpp @@ -12,9 +12,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/bedrock-gen-tests/BedrockIncludeTests.cpp b/generated/tests/bedrock-gen-tests/BedrockIncludeTests.cpp index 16321940701e..636114e10003 100644 --- a/generated/tests/bedrock-gen-tests/BedrockIncludeTests.cpp +++ b/generated/tests/bedrock-gen-tests/BedrockIncludeTests.cpp @@ -9,12 +9,16 @@ #include #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -386,46 +390,65 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/bedrock-runtime-gen-tests/BedrockRuntimeIncludeTests.cpp b/generated/tests/bedrock-runtime-gen-tests/BedrockRuntimeIncludeTests.cpp index 7ee834e47ab1..395b2103660d 100644 --- a/generated/tests/bedrock-runtime-gen-tests/BedrockRuntimeIncludeTests.cpp +++ b/generated/tests/bedrock-runtime-gen-tests/BedrockRuntimeIncludeTests.cpp @@ -9,12 +9,16 @@ #include #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -188,6 +192,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/billing-gen-tests/BillingIncludeTests.cpp b/generated/tests/billing-gen-tests/BillingIncludeTests.cpp index ba3c49946054..5f4ea9c3dc58 100644 --- a/generated/tests/billing-gen-tests/BillingIncludeTests.cpp +++ b/generated/tests/billing-gen-tests/BillingIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -53,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -64,10 +69,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/billingconductor-gen-tests/BillingConductorIncludeTests.cpp b/generated/tests/billingconductor-gen-tests/BillingConductorIncludeTests.cpp index e3fc8993d056..9b3064250ca9 100644 --- a/generated/tests/billingconductor-gen-tests/BillingConductorIncludeTests.cpp +++ b/generated/tests/billingconductor-gen-tests/BillingConductorIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -70,6 +74,7 @@ #include #include #include +#include #include #include #include @@ -78,13 +83,16 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include +#include #include #include #include @@ -92,22 +100,29 @@ #include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include #include diff --git a/generated/tests/braket-gen-tests/BraketIncludeTests.cpp b/generated/tests/braket-gen-tests/BraketIncludeTests.cpp index b15061096da3..d25f1e5fb665 100644 --- a/generated/tests/braket-gen-tests/BraketIncludeTests.cpp +++ b/generated/tests/braket-gen-tests/BraketIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -70,18 +74,22 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/budgets-gen-tests/BudgetsIncludeTests.cpp b/generated/tests/budgets-gen-tests/BudgetsIncludeTests.cpp index 0c6eb6d8e6e9..217387558d07 100644 --- a/generated/tests/budgets-gen-tests/BudgetsIncludeTests.cpp +++ b/generated/tests/budgets-gen-tests/BudgetsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -49,24 +53,32 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/ce-gen-tests/CostExplorerIncludeTests.cpp b/generated/tests/ce-gen-tests/CostExplorerIncludeTests.cpp index 9279bce6ac18..3fa8895fe43b 100644 --- a/generated/tests/ce-gen-tests/CostExplorerIncludeTests.cpp +++ b/generated/tests/ce-gen-tests/CostExplorerIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -93,16 +97,20 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -111,6 +119,7 @@ #include #include #include +#include #include #include #include @@ -119,18 +128,22 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -145,16 +158,22 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/chatbot-gen-tests/ChatbotIncludeTests.cpp b/generated/tests/chatbot-gen-tests/ChatbotIncludeTests.cpp index 2140b8884c7b..a881483bded0 100644 --- a/generated/tests/chatbot-gen-tests/ChatbotIncludeTests.cpp +++ b/generated/tests/chatbot-gen-tests/ChatbotIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -48,12 +52,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -64,14 +72,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/chime-gen-tests/ChimeIncludeTests.cpp b/generated/tests/chime-gen-tests/ChimeIncludeTests.cpp index 6f9941af885c..ed36a1e50562 100644 --- a/generated/tests/chime-gen-tests/ChimeIncludeTests.cpp +++ b/generated/tests/chime-gen-tests/ChimeIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -99,20 +103,27 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -156,6 +167,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/chime-sdk-identity-gen-tests/ChimeSDKIdentityIncludeTests.cpp b/generated/tests/chime-sdk-identity-gen-tests/ChimeSDKIdentityIncludeTests.cpp index 249c990d748d..e29d2a79b0d2 100644 --- a/generated/tests/chime-sdk-identity-gen-tests/ChimeSDKIdentityIncludeTests.cpp +++ b/generated/tests/chime-sdk-identity-gen-tests/ChimeSDKIdentityIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -66,14 +70,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/chime-sdk-media-pipelines-gen-tests/ChimeSDKMediaPipelinesIncludeTests.cpp b/generated/tests/chime-sdk-media-pipelines-gen-tests/ChimeSDKMediaPipelinesIncludeTests.cpp index 167f63306e21..2f7e83d59bf7 100644 --- a/generated/tests/chime-sdk-media-pipelines-gen-tests/ChimeSDKMediaPipelinesIncludeTests.cpp +++ b/generated/tests/chime-sdk-media-pipelines-gen-tests/ChimeSDKMediaPipelinesIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -99,12 +103,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/chime-sdk-meetings-gen-tests/ChimeSDKMeetingsIncludeTests.cpp b/generated/tests/chime-sdk-meetings-gen-tests/ChimeSDKMeetingsIncludeTests.cpp index 29bc6c417412..3d0cf9db3f64 100644 --- a/generated/tests/chime-sdk-meetings-gen-tests/ChimeSDKMeetingsIncludeTests.cpp +++ b/generated/tests/chime-sdk-meetings-gen-tests/ChimeSDKMeetingsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -43,6 +47,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/chime-sdk-messaging-gen-tests/ChimeSDKMessagingIncludeTests.cpp b/generated/tests/chime-sdk-messaging-gen-tests/ChimeSDKMessagingIncludeTests.cpp index d4c7889c9a34..97d02974cfd5 100644 --- a/generated/tests/chime-sdk-messaging-gen-tests/ChimeSDKMessagingIncludeTests.cpp +++ b/generated/tests/chime-sdk-messaging-gen-tests/ChimeSDKMessagingIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -99,24 +103,34 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -140,6 +154,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/chime-sdk-voice-gen-tests/ChimeSDKVoiceIncludeTests.cpp b/generated/tests/chime-sdk-voice-gen-tests/ChimeSDKVoiceIncludeTests.cpp index ea43b7fb0763..f09ad50c9fe8 100644 --- a/generated/tests/chime-sdk-voice-gen-tests/ChimeSDKVoiceIncludeTests.cpp +++ b/generated/tests/chime-sdk-voice-gen-tests/ChimeSDKVoiceIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -113,26 +117,34 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -178,6 +190,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/cleanrooms-gen-tests/CleanRoomsIncludeTests.cpp b/generated/tests/cleanrooms-gen-tests/CleanRoomsIncludeTests.cpp index de6bdc5e03c0..a0cdefa83c2c 100644 --- a/generated/tests/cleanrooms-gen-tests/CleanRoomsIncludeTests.cpp +++ b/generated/tests/cleanrooms-gen-tests/CleanRoomsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -300,50 +304,73 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/cleanroomsml-gen-tests/CleanRoomsMLIncludeTests.cpp b/generated/tests/cleanroomsml-gen-tests/CleanRoomsMLIncludeTests.cpp index 1310706ff2b2..854a1af40cfe 100644 --- a/generated/tests/cleanroomsml-gen-tests/CleanRoomsMLIncludeTests.cpp +++ b/generated/tests/cleanroomsml-gen-tests/CleanRoomsMLIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -118,38 +122,54 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/cloud9-gen-tests/Cloud9IncludeTests.cpp b/generated/tests/cloud9-gen-tests/Cloud9IncludeTests.cpp index ed87e0e389d6..cdf491bbc579 100644 --- a/generated/tests/cloud9-gen-tests/Cloud9IncludeTests.cpp +++ b/generated/tests/cloud9-gen-tests/Cloud9IncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -22,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +39,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/cloudcontrol-gen-tests/CloudControlApiIncludeTests.cpp b/generated/tests/cloudcontrol-gen-tests/CloudControlApiIncludeTests.cpp index 7e2158497517..4923a0a9599d 100644 --- a/generated/tests/cloudcontrol-gen-tests/CloudControlApiIncludeTests.cpp +++ b/generated/tests/cloudcontrol-gen-tests/CloudControlApiIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -25,8 +29,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/clouddirectory-gen-tests/CloudDirectoryIncludeTests.cpp b/generated/tests/clouddirectory-gen-tests/CloudDirectoryIncludeTests.cpp index bf99d714f90c..dfadb55ea40c 100644 --- a/generated/tests/clouddirectory-gen-tests/CloudDirectoryIncludeTests.cpp +++ b/generated/tests/clouddirectory-gen-tests/CloudDirectoryIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -161,46 +165,65 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/cloudformation-gen-tests/CloudFormationIncludeTests.cpp b/generated/tests/cloudformation-gen-tests/CloudFormationIncludeTests.cpp index fcfa7e0e009f..6519a6a031c8 100644 --- a/generated/tests/cloudformation-gen-tests/CloudFormationIncludeTests.cpp +++ b/generated/tests/cloudformation-gen-tests/CloudFormationIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -82,12 +86,15 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include @@ -100,12 +107,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -116,6 +125,7 @@ #include #include #include +#include #include #include #include @@ -166,47 +176,65 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/cloudfront-gen-tests/CloudFrontIncludeTests.cpp b/generated/tests/cloudfront-gen-tests/CloudFrontIncludeTests.cpp index 882b715efb6c..3c12bba27580 100644 --- a/generated/tests/cloudfront-gen-tests/CloudFrontIncludeTests.cpp +++ b/generated/tests/cloudfront-gen-tests/CloudFrontIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -323,18 +327,23 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include +#include #include #include #include @@ -343,8 +352,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -357,12 +368,15 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include @@ -373,26 +387,33 @@ #include #include #include +#include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/cloudfront-keyvaluestore-gen-tests/CloudFrontKeyValueStoreIncludeTests.cpp b/generated/tests/cloudfront-keyvaluestore-gen-tests/CloudFrontKeyValueStoreIncludeTests.cpp index e3a0fe4c9bc0..17c746c62d93 100644 --- a/generated/tests/cloudfront-keyvaluestore-gen-tests/CloudFrontKeyValueStoreIncludeTests.cpp +++ b/generated/tests/cloudfront-keyvaluestore-gen-tests/CloudFrontKeyValueStoreIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -20,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/cloudhsm-gen-tests/CloudHSMIncludeTests.cpp b/generated/tests/cloudhsm-gen-tests/CloudHSMIncludeTests.cpp index a32e01097cbb..17bbb8adb495 100644 --- a/generated/tests/cloudhsm-gen-tests/CloudHSMIncludeTests.cpp +++ b/generated/tests/cloudhsm-gen-tests/CloudHSMIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/cloudhsmv2-gen-tests/CloudHSMV2IncludeTests.cpp b/generated/tests/cloudhsmv2-gen-tests/CloudHSMV2IncludeTests.cpp index 896c4636fd6d..afad1270e0a4 100644 --- a/generated/tests/cloudhsmv2-gen-tests/CloudHSMV2IncludeTests.cpp +++ b/generated/tests/cloudhsmv2-gen-tests/CloudHSMV2IncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -36,8 +40,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -47,6 +53,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/cloudsearch-gen-tests/CloudSearchIncludeTests.cpp b/generated/tests/cloudsearch-gen-tests/CloudSearchIncludeTests.cpp index d8e53b464c21..f3322be997cb 100644 --- a/generated/tests/cloudsearch-gen-tests/CloudSearchIncludeTests.cpp +++ b/generated/tests/cloudsearch-gen-tests/CloudSearchIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/cloudsearchdomain-gen-tests/CloudSearchDomainIncludeTests.cpp b/generated/tests/cloudsearchdomain-gen-tests/CloudSearchDomainIncludeTests.cpp index b59ca37a17ef..9fdeafc4578e 100644 --- a/generated/tests/cloudsearchdomain-gen-tests/CloudSearchDomainIncludeTests.cpp +++ b/generated/tests/cloudsearchdomain-gen-tests/CloudSearchDomainIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/cloudtrail-data-gen-tests/CloudTrailDataIncludeTests.cpp b/generated/tests/cloudtrail-data-gen-tests/CloudTrailDataIncludeTests.cpp index 50408af2a810..fb887160cd27 100644 --- a/generated/tests/cloudtrail-data-gen-tests/CloudTrailDataIncludeTests.cpp +++ b/generated/tests/cloudtrail-data-gen-tests/CloudTrailDataIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/cloudtrail-gen-tests/CloudTrailIncludeTests.cpp b/generated/tests/cloudtrail-gen-tests/CloudTrailIncludeTests.cpp index 90a2d3a7d1ab..aefa462426e0 100644 --- a/generated/tests/cloudtrail-gen-tests/CloudTrailIncludeTests.cpp +++ b/generated/tests/cloudtrail-gen-tests/CloudTrailIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -81,6 +85,7 @@ #include #include #include +#include #include #include #include @@ -99,32 +104,43 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/codeartifact-gen-tests/CodeArtifactIncludeTests.cpp b/generated/tests/codeartifact-gen-tests/CodeArtifactIncludeTests.cpp index 5693b6798aad..2f50fd4186f5 100644 --- a/generated/tests/codeartifact-gen-tests/CodeArtifactIncludeTests.cpp +++ b/generated/tests/codeartifact-gen-tests/CodeArtifactIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -78,26 +82,36 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/codebuild-gen-tests/CodeBuildIncludeTests.cpp b/generated/tests/codebuild-gen-tests/CodeBuildIncludeTests.cpp index 1456883a12a5..4001d7e64a2b 100644 --- a/generated/tests/codebuild-gen-tests/CodeBuildIncludeTests.cpp +++ b/generated/tests/codebuild-gen-tests/CodeBuildIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -86,8 +90,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -124,34 +130,48 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/codecatalyst-gen-tests/CodeCatalystIncludeTests.cpp b/generated/tests/codecatalyst-gen-tests/CodeCatalystIncludeTests.cpp index 7dd9ff3224b5..fb0f50aadc9d 100644 --- a/generated/tests/codecatalyst-gen-tests/CodeCatalystIncludeTests.cpp +++ b/generated/tests/codecatalyst-gen-tests/CodeCatalystIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -69,26 +73,36 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/codecommit-gen-tests/CodeCommitIncludeTests.cpp b/generated/tests/codecommit-gen-tests/CodeCommitIncludeTests.cpp index fa5523d463e1..752c9afbcda7 100644 --- a/generated/tests/codecommit-gen-tests/CodeCommitIncludeTests.cpp +++ b/generated/tests/codecommit-gen-tests/CodeCommitIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -75,8 +79,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -97,16 +103,20 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -115,6 +125,7 @@ #include #include #include +#include #include #include #include @@ -130,18 +141,25 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/codeconnections-gen-tests/CodeConnectionsIncludeTests.cpp b/generated/tests/codeconnections-gen-tests/CodeConnectionsIncludeTests.cpp index ba37a8c4d970..c65e0def9b55 100644 --- a/generated/tests/codeconnections-gen-tests/CodeConnectionsIncludeTests.cpp +++ b/generated/tests/codeconnections-gen-tests/CodeConnectionsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -48,14 +52,18 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/codedeploy-gen-tests/CodeDeployIncludeTests.cpp b/generated/tests/codedeploy-gen-tests/CodeDeployIncludeTests.cpp index 116aefde4a5b..4b83bcfd3a5d 100644 --- a/generated/tests/codedeploy-gen-tests/CodeDeployIncludeTests.cpp +++ b/generated/tests/codedeploy-gen-tests/CodeDeployIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -112,16 +116,21 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/codeguru-reviewer-gen-tests/CodeGuruReviewerIncludeTests.cpp b/generated/tests/codeguru-reviewer-gen-tests/CodeGuruReviewerIncludeTests.cpp index f0a906147f4e..235b34c6b47d 100644 --- a/generated/tests/codeguru-reviewer-gen-tests/CodeGuruReviewerIncludeTests.cpp +++ b/generated/tests/codeguru-reviewer-gen-tests/CodeGuruReviewerIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -38,12 +42,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/codeguru-security-gen-tests/CodeGuruSecurityIncludeTests.cpp b/generated/tests/codeguru-security-gen-tests/CodeGuruSecurityIncludeTests.cpp index 3e3c25b37c85..c08467199510 100644 --- a/generated/tests/codeguru-security-gen-tests/CodeGuruSecurityIncludeTests.cpp +++ b/generated/tests/codeguru-security-gen-tests/CodeGuruSecurityIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -34,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -41,8 +46,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/codeguruprofiler-gen-tests/CodeGuruProfilerIncludeTests.cpp b/generated/tests/codeguruprofiler-gen-tests/CodeGuruProfilerIncludeTests.cpp index ce733ac05895..cc9dc02aaf38 100644 --- a/generated/tests/codeguruprofiler-gen-tests/CodeGuruProfilerIncludeTests.cpp +++ b/generated/tests/codeguruprofiler-gen-tests/CodeGuruProfilerIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -40,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -50,10 +55,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/codepipeline-gen-tests/CodePipelineIncludeTests.cpp b/generated/tests/codepipeline-gen-tests/CodePipelineIncludeTests.cpp index 09c7d67bebf0..73330b227988 100644 --- a/generated/tests/codepipeline-gen-tests/CodePipelineIncludeTests.cpp +++ b/generated/tests/codepipeline-gen-tests/CodePipelineIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -119,23 +123,31 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include +#include #include #include #include diff --git a/generated/tests/codestar-connections-gen-tests/CodeStarconnectionsIncludeTests.cpp b/generated/tests/codestar-connections-gen-tests/CodeStarconnectionsIncludeTests.cpp index 6e894bd8968c..e22ca1233654 100644 --- a/generated/tests/codestar-connections-gen-tests/CodeStarconnectionsIncludeTests.cpp +++ b/generated/tests/codestar-connections-gen-tests/CodeStarconnectionsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -48,14 +52,18 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/codestar-notifications-gen-tests/CodeStarNotificationsIncludeTests.cpp b/generated/tests/codestar-notifications-gen-tests/CodeStarNotificationsIncludeTests.cpp index e899e872c3c2..1c17a6d5de88 100644 --- a/generated/tests/codestar-notifications-gen-tests/CodeStarNotificationsIncludeTests.cpp +++ b/generated/tests/codestar-notifications-gen-tests/CodeStarNotificationsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -25,16 +29,19 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/cognito-identity-gen-tests/CognitoIdentityIncludeTests.cpp b/generated/tests/cognito-identity-gen-tests/CognitoIdentityIncludeTests.cpp index 01a148d190d8..0edd645bf7d9 100644 --- a/generated/tests/cognito-identity-gen-tests/CognitoIdentityIncludeTests.cpp +++ b/generated/tests/cognito-identity-gen-tests/CognitoIdentityIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -42,6 +46,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/cognito-idp-gen-tests/CognitoIdentityProviderIncludeTests.cpp b/generated/tests/cognito-idp-gen-tests/CognitoIdentityProviderIncludeTests.cpp index c57ef56a4f75..5caeddb7f65f 100644 --- a/generated/tests/cognito-idp-gen-tests/CognitoIdentityProviderIncludeTests.cpp +++ b/generated/tests/cognito-idp-gen-tests/CognitoIdentityProviderIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -50,8 +54,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -251,10 +257,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -265,14 +274,18 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/cognito-sync-gen-tests/CognitoSyncIncludeTests.cpp b/generated/tests/cognito-sync-gen-tests/CognitoSyncIncludeTests.cpp index 608fb5021308..f33df32d19ba 100644 --- a/generated/tests/cognito-sync-gen-tests/CognitoSyncIncludeTests.cpp +++ b/generated/tests/cognito-sync-gen-tests/CognitoSyncIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/comprehend-gen-tests/ComprehendIncludeTests.cpp b/generated/tests/comprehend-gen-tests/ComprehendIncludeTests.cpp index 97245b8b96ba..3ed11f94fee0 100644 --- a/generated/tests/comprehend-gen-tests/ComprehendIncludeTests.cpp +++ b/generated/tests/comprehend-gen-tests/ComprehendIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -199,40 +203,57 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/comprehendmedical-gen-tests/ComprehendMedicalIncludeTests.cpp b/generated/tests/comprehendmedical-gen-tests/ComprehendMedicalIncludeTests.cpp index a1391016822a..77b3dc08a627 100644 --- a/generated/tests/comprehendmedical-gen-tests/ComprehendMedicalIncludeTests.cpp +++ b/generated/tests/comprehendmedical-gen-tests/ComprehendMedicalIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/compute-optimizer-automation-gen-tests/ComputeOptimizerAutomationIncludeTests.cpp b/generated/tests/compute-optimizer-automation-gen-tests/ComputeOptimizerAutomationIncludeTests.cpp index af544ecc3a65..5773df7874e8 100644 --- a/generated/tests/compute-optimizer-automation-gen-tests/ComputeOptimizerAutomationIncludeTests.cpp +++ b/generated/tests/compute-optimizer-automation-gen-tests/ComputeOptimizerAutomationIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -46,22 +50,31 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/compute-optimizer-gen-tests/ComputeOptimizerIncludeTests.cpp b/generated/tests/compute-optimizer-gen-tests/ComputeOptimizerIncludeTests.cpp index 6bc1f360b0f9..2aa68c1feb69 100644 --- a/generated/tests/compute-optimizer-gen-tests/ComputeOptimizerIncludeTests.cpp +++ b/generated/tests/compute-optimizer-gen-tests/ComputeOptimizerIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -35,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -122,10 +127,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -135,8 +142,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/config-gen-tests/ConfigServiceIncludeTests.cpp b/generated/tests/config-gen-tests/ConfigServiceIncludeTests.cpp index 7bf3fcb9659a..ba2ea3c39161 100644 --- a/generated/tests/config-gen-tests/ConfigServiceIncludeTests.cpp +++ b/generated/tests/config-gen-tests/ConfigServiceIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -111,55 +115,75 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -180,40 +204,52 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -221,20 +257,28 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -329,8 +373,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/connect-contact-lens-gen-tests/ConnectContactLensIncludeTests.cpp b/generated/tests/connect-contact-lens-gen-tests/ConnectContactLensIncludeTests.cpp index a7f42c8c9332..b9ed18b34e8b 100644 --- a/generated/tests/connect-contact-lens-gen-tests/ConnectContactLensIncludeTests.cpp +++ b/generated/tests/connect-contact-lens-gen-tests/ConnectContactLensIncludeTests.cpp @@ -7,16 +7,21 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/connect-gen-tests/ConnectIncludeTests.cpp b/generated/tests/connect-gen-tests/ConnectIncludeTests.cpp index e08aa71d8032..769a11cff795 100644 --- a/generated/tests/connect-gen-tests/ConnectIncludeTests.cpp +++ b/generated/tests/connect-gen-tests/ConnectIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -522,6 +526,7 @@ #include #include #include +#include #include #include #include @@ -644,8 +649,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -656,8 +663,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -736,147 +745,207 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include @@ -1109,19 +1178,24 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -1129,48 +1203,67 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/connectcampaigns-gen-tests/ConnectCampaignsIncludeTests.cpp b/generated/tests/connectcampaigns-gen-tests/ConnectCampaignsIncludeTests.cpp index e81d17713bda..6f68feef7582 100644 --- a/generated/tests/connectcampaigns-gen-tests/ConnectCampaignsIncludeTests.cpp +++ b/generated/tests/connectcampaigns-gen-tests/ConnectCampaignsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -53,6 +57,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/connectcampaignsv2-gen-tests/ConnectCampaignsV2IncludeTests.cpp b/generated/tests/connectcampaignsv2-gen-tests/ConnectCampaignsV2IncludeTests.cpp index 13d81037d081..2c9640b73349 100644 --- a/generated/tests/connectcampaignsv2-gen-tests/ConnectCampaignsV2IncludeTests.cpp +++ b/generated/tests/connectcampaignsv2-gen-tests/ConnectCampaignsV2IncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -95,8 +99,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/connectcases-gen-tests/ConnectCasesIncludeTests.cpp b/generated/tests/connectcases-gen-tests/ConnectCasesIncludeTests.cpp index ec58f3aa421e..8536e23c18ae 100644 --- a/generated/tests/connectcases-gen-tests/ConnectCasesIncludeTests.cpp +++ b/generated/tests/connectcases-gen-tests/ConnectCasesIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -100,10 +104,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -120,20 +126,27 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -152,14 +165,17 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include +#include #include #include #include diff --git a/generated/tests/connecthealth-gen-tests/ConnectHealthIncludeTests.cpp b/generated/tests/connecthealth-gen-tests/ConnectHealthIncludeTests.cpp index e4abdc0621c3..e10fc52b6773 100644 --- a/generated/tests/connecthealth-gen-tests/ConnectHealthIncludeTests.cpp +++ b/generated/tests/connecthealth-gen-tests/ConnectHealthIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -50,8 +54,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/connectparticipant-gen-tests/ConnectParticipantIncludeTests.cpp b/generated/tests/connectparticipant-gen-tests/ConnectParticipantIncludeTests.cpp index d4eff4ec5f05..6f715c495ac6 100644 --- a/generated/tests/connectparticipant-gen-tests/ConnectParticipantIncludeTests.cpp +++ b/generated/tests/connectparticipant-gen-tests/ConnectParticipantIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -34,6 +38,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/controlcatalog-gen-tests/ControlCatalogIncludeTests.cpp b/generated/tests/controlcatalog-gen-tests/ControlCatalogIncludeTests.cpp index 2ac78b46fac4..5dd2a84703f9 100644 --- a/generated/tests/controlcatalog-gen-tests/ControlCatalogIncludeTests.cpp +++ b/generated/tests/controlcatalog-gen-tests/ControlCatalogIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -36,14 +40,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/controltower-gen-tests/ControlTowerIncludeTests.cpp b/generated/tests/controltower-gen-tests/ControlTowerIncludeTests.cpp index ec36ed434cdf..4728cb493b6c 100644 --- a/generated/tests/controltower-gen-tests/ControlTowerIncludeTests.cpp +++ b/generated/tests/controltower-gen-tests/ControlTowerIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -79,16 +83,22 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/cost-optimization-hub-gen-tests/CostOptimizationHubIncludeTests.cpp b/generated/tests/cost-optimization-hub-gen-tests/CostOptimizationHubIncludeTests.cpp index cffad2255422..cb95cdcea5e1 100644 --- a/generated/tests/cost-optimization-hub-gen-tests/CostOptimizationHubIncludeTests.cpp +++ b/generated/tests/cost-optimization-hub-gen-tests/CostOptimizationHubIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -56,12 +60,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/cur-gen-tests/CostandUsageReportServiceIncludeTests.cpp b/generated/tests/cur-gen-tests/CostandUsageReportServiceIncludeTests.cpp index e87ab41259a9..ca73d46b0308 100644 --- a/generated/tests/cur-gen-tests/CostandUsageReportServiceIncludeTests.cpp +++ b/generated/tests/cur-gen-tests/CostandUsageReportServiceIncludeTests.cpp @@ -7,17 +7,22 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/customer-profiles-gen-tests/CustomerProfilesIncludeTests.cpp b/generated/tests/customer-profiles-gen-tests/CustomerProfilesIncludeTests.cpp index 82cd8d90f0aa..d9f8987ad634 100644 --- a/generated/tests/customer-profiles-gen-tests/CustomerProfilesIncludeTests.cpp +++ b/generated/tests/customer-profiles-gen-tests/CustomerProfilesIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -208,6 +212,7 @@ #include #include #include +#include #include #include #include @@ -240,14 +245,18 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include @@ -259,6 +268,7 @@ #include #include #include +#include #include #include #include @@ -274,20 +284,27 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/databrew-gen-tests/GlueDataBrewIncludeTests.cpp b/generated/tests/databrew-gen-tests/GlueDataBrewIncludeTests.cpp index 0f7ca5f8ed9d..438dd2ff4528 100644 --- a/generated/tests/databrew-gen-tests/GlueDataBrewIncludeTests.cpp +++ b/generated/tests/databrew-gen-tests/GlueDataBrewIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -86,20 +90,28 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/dataexchange-gen-tests/DataExchangeIncludeTests.cpp b/generated/tests/dataexchange-gen-tests/DataExchangeIncludeTests.cpp index d0020c793257..8feec4c3b492 100644 --- a/generated/tests/dataexchange-gen-tests/DataExchangeIncludeTests.cpp +++ b/generated/tests/dataexchange-gen-tests/DataExchangeIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -106,18 +110,25 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/datapipeline-gen-tests/DataPipelineIncludeTests.cpp b/generated/tests/datapipeline-gen-tests/DataPipelineIncludeTests.cpp index 528eeb5ea9b5..e4c37ca13aa8 100644 --- a/generated/tests/datapipeline-gen-tests/DataPipelineIncludeTests.cpp +++ b/generated/tests/datapipeline-gen-tests/DataPipelineIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -22,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -32,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +53,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/datasync-gen-tests/DataSyncIncludeTests.cpp b/generated/tests/datasync-gen-tests/DataSyncIncludeTests.cpp index 57808b1516d8..6fceb48bb9b8 100644 --- a/generated/tests/datasync-gen-tests/DataSyncIncludeTests.cpp +++ b/generated/tests/datasync-gen-tests/DataSyncIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -101,14 +105,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/datazone-gen-tests/DataZoneIncludeTests.cpp b/generated/tests/datazone-gen-tests/DataZoneIncludeTests.cpp index b394de3b7e8b..dae03a1ffcfd 100644 --- a/generated/tests/datazone-gen-tests/DataZoneIncludeTests.cpp +++ b/generated/tests/datazone-gen-tests/DataZoneIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -456,74 +460,108 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -617,6 +655,7 @@ #include #include #include +#include #include #include #include @@ -679,20 +718,25 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include +#include #include #include #include #include +#include #include #include #include +#include #include #include #include diff --git a/generated/tests/dax-gen-tests/DAXIncludeTests.cpp b/generated/tests/dax-gen-tests/DAXIncludeTests.cpp index 0df402c1d308..9549e115babc 100644 --- a/generated/tests/dax-gen-tests/DAXIncludeTests.cpp +++ b/generated/tests/dax-gen-tests/DAXIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/deadline-gen-tests/DeadlineIncludeTests.cpp b/generated/tests/deadline-gen-tests/DeadlineIncludeTests.cpp index f59ee04323ec..9279bf99b61c 100644 --- a/generated/tests/deadline-gen-tests/DeadlineIncludeTests.cpp +++ b/generated/tests/deadline-gen-tests/DeadlineIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -237,6 +241,7 @@ #include #include #include +#include #include #include #include @@ -279,64 +284,93 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/detective-gen-tests/DetectiveIncludeTests.cpp b/generated/tests/detective-gen-tests/DetectiveIncludeTests.cpp index 60dc4fa2d356..74ed596d728e 100644 --- a/generated/tests/detective-gen-tests/DetectiveIncludeTests.cpp +++ b/generated/tests/detective-gen-tests/DetectiveIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -54,18 +58,23 @@ #include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/devicefarm-gen-tests/DeviceFarmIncludeTests.cpp b/generated/tests/devicefarm-gen-tests/DeviceFarmIncludeTests.cpp index f8a64c33bad9..1860db24ab28 100644 --- a/generated/tests/devicefarm-gen-tests/DeviceFarmIncludeTests.cpp +++ b/generated/tests/devicefarm-gen-tests/DeviceFarmIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -95,6 +99,7 @@ #include #include #include +#include #include #include #include @@ -125,50 +130,67 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/devops-agent-gen-tests/DevOpsAgentIncludeTests.cpp b/generated/tests/devops-agent-gen-tests/DevOpsAgentIncludeTests.cpp index 7c124f9c6020..83767ac8cf66 100644 --- a/generated/tests/devops-agent-gen-tests/DevOpsAgentIncludeTests.cpp +++ b/generated/tests/devops-agent-gen-tests/DevOpsAgentIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -122,26 +126,36 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -150,10 +164,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/devops-guru-gen-tests/DevOpsGuruIncludeTests.cpp b/generated/tests/devops-guru-gen-tests/DevOpsGuruIncludeTests.cpp index 46c57882410b..3d3f37da3bf6 100644 --- a/generated/tests/devops-guru-gen-tests/DevOpsGuruIncludeTests.cpp +++ b/generated/tests/devops-guru-gen-tests/DevOpsGuruIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -59,8 +63,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -73,8 +79,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -88,26 +96,34 @@ #include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -162,9 +178,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include diff --git a/generated/tests/directconnect-gen-tests/DirectConnectIncludeTests.cpp b/generated/tests/directconnect-gen-tests/DirectConnectIncludeTests.cpp index 00a7d65c7d42..1cc6d1c254cc 100644 --- a/generated/tests/directconnect-gen-tests/DirectConnectIncludeTests.cpp +++ b/generated/tests/directconnect-gen-tests/DirectConnectIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/directory-service-data-gen-tests/DirectoryServiceDataIncludeTests.cpp b/generated/tests/directory-service-data-gen-tests/DirectoryServiceDataIncludeTests.cpp index 5d56f3134ecc..85831b92614b 100644 --- a/generated/tests/directory-service-data-gen-tests/DirectoryServiceDataIncludeTests.cpp +++ b/generated/tests/directory-service-data-gen-tests/DirectoryServiceDataIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -38,20 +42,26 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/discovery-gen-tests/ApplicationDiscoveryServiceIncludeTests.cpp b/generated/tests/discovery-gen-tests/ApplicationDiscoveryServiceIncludeTests.cpp index 139e5fb65e10..82649ebea55c 100644 --- a/generated/tests/discovery-gen-tests/ApplicationDiscoveryServiceIncludeTests.cpp +++ b/generated/tests/discovery-gen-tests/ApplicationDiscoveryServiceIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -49,18 +53,23 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -80,6 +89,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/dlm-gen-tests/DLMIncludeTests.cpp b/generated/tests/dlm-gen-tests/DLMIncludeTests.cpp index db5634649e7e..93ac230f4f05 100644 --- a/generated/tests/dlm-gen-tests/DLMIncludeTests.cpp +++ b/generated/tests/dlm-gen-tests/DLMIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/dms-gen-tests/DatabaseMigrationServiceIncludeTests.cpp b/generated/tests/dms-gen-tests/DatabaseMigrationServiceIncludeTests.cpp index 7330a0129edf..169d33846949 100644 --- a/generated/tests/dms-gen-tests/DatabaseMigrationServiceIncludeTests.cpp +++ b/generated/tests/dms-gen-tests/DatabaseMigrationServiceIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -109,96 +113,138 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/docdb-elastic-gen-tests/DocDBElasticIncludeTests.cpp b/generated/tests/docdb-elastic-gen-tests/DocDBElasticIncludeTests.cpp index 85b7265c25f6..f19abd56d740 100644 --- a/generated/tests/docdb-elastic-gen-tests/DocDBElasticIncludeTests.cpp +++ b/generated/tests/docdb-elastic-gen-tests/DocDBElasticIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -37,10 +41,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/docdb-gen-tests/DocDBIncludeTests.cpp b/generated/tests/docdb-gen-tests/DocDBIncludeTests.cpp index 433b5d99edff..2a5fd7f342e6 100644 --- a/generated/tests/docdb-gen-tests/DocDBIncludeTests.cpp +++ b/generated/tests/docdb-gen-tests/DocDBIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -65,36 +69,49 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/drs-gen-tests/DrsIncludeTests.cpp b/generated/tests/drs-gen-tests/DrsIncludeTests.cpp index 1831fa971968..912b6916692d 100644 --- a/generated/tests/drs-gen-tests/DrsIncludeTests.cpp +++ b/generated/tests/drs-gen-tests/DrsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -50,24 +54,32 @@ #include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include @@ -120,10 +132,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/ds-gen-tests/DirectoryServiceIncludeTests.cpp b/generated/tests/ds-gen-tests/DirectoryServiceIncludeTests.cpp index 4823e235a0ec..082e0a6a0626 100644 --- a/generated/tests/ds-gen-tests/DirectoryServiceIncludeTests.cpp +++ b/generated/tests/ds-gen-tests/DirectoryServiceIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -91,32 +95,41 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -197,16 +210,22 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/dsql-gen-tests/DSQLIncludeTests.cpp b/generated/tests/dsql-gen-tests/DSQLIncludeTests.cpp index c64bc83aebc6..26a05b51f908 100644 --- a/generated/tests/dsql-gen-tests/DSQLIncludeTests.cpp +++ b/generated/tests/dsql-gen-tests/DSQLIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -39,8 +43,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/dynamodb-gen-tests/DynamoDBIncludeTests.cpp b/generated/tests/dynamodb-gen-tests/DynamoDBIncludeTests.cpp index d787fb7f1619..62c494bc7353 100644 --- a/generated/tests/dynamodb-gen-tests/DynamoDBIncludeTests.cpp +++ b/generated/tests/dynamodb-gen-tests/DynamoDBIncludeTests.cpp @@ -8,12 +8,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -169,14 +173,18 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include @@ -203,6 +211,7 @@ #include #include #include +#include #include #include #include @@ -237,6 +246,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/dynamodbstreams-gen-tests/DynamoDBStreamsIncludeTests.cpp b/generated/tests/dynamodbstreams-gen-tests/DynamoDBStreamsIncludeTests.cpp index 1051de90567b..caa655d73fdd 100644 --- a/generated/tests/dynamodbstreams-gen-tests/DynamoDBStreamsIncludeTests.cpp +++ b/generated/tests/dynamodbstreams-gen-tests/DynamoDBStreamsIncludeTests.cpp @@ -11,9 +11,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/ebs-gen-tests/EBSIncludeTests.cpp b/generated/tests/ebs-gen-tests/EBSIncludeTests.cpp index db2bc2db1a25..7b149c734c31 100644 --- a/generated/tests/ebs-gen-tests/EBSIncludeTests.cpp +++ b/generated/tests/ebs-gen-tests/EBSIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -23,8 +27,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/ec2-gen-tests/EC2IncludeTests.cpp b/generated/tests/ec2-gen-tests/EC2IncludeTests.cpp index 875770ae0e87..27ee22de928a 100644 --- a/generated/tests/ec2-gen-tests/EC2IncludeTests.cpp +++ b/generated/tests/ec2-gen-tests/EC2IncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -831,8 +835,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -847,48 +853,67 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -897,20 +922,25 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -919,20 +949,27 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -941,44 +978,60 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -989,124 +1042,173 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include #include @@ -1115,68 +1217,97 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -1185,6 +1316,7 @@ #include #include #include +#include #include #include #include @@ -1193,22 +1325,30 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -1517,16 +1657,21 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -1549,6 +1694,7 @@ #include #include #include +#include #include #include #include @@ -1561,16 +1707,20 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -1583,16 +1733,22 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -1605,12 +1761,15 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -1625,30 +1784,39 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -1661,6 +1829,7 @@ #include #include #include +#include #include #include #include @@ -2021,8 +2190,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -2602,10 +2773,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/ec2-instance-connect-gen-tests/EC2InstanceConnectIncludeTests.cpp b/generated/tests/ec2-instance-connect-gen-tests/EC2InstanceConnectIncludeTests.cpp index 4fa487a1effe..133b2cfa3476 100644 --- a/generated/tests/ec2-instance-connect-gen-tests/EC2InstanceConnectIncludeTests.cpp +++ b/generated/tests/ec2-instance-connect-gen-tests/EC2InstanceConnectIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/ecr-gen-tests/ECRIncludeTests.cpp b/generated/tests/ecr-gen-tests/ECRIncludeTests.cpp index b5fa5bd1ded1..f772ea7a3d99 100644 --- a/generated/tests/ecr-gen-tests/ECRIncludeTests.cpp +++ b/generated/tests/ecr-gen-tests/ECRIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -55,19 +59,24 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include @@ -81,6 +90,7 @@ #include #include #include +#include #include #include #include @@ -131,6 +141,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/ecr-public-gen-tests/ECRPublicIncludeTests.cpp b/generated/tests/ecr-public-gen-tests/ECRPublicIncludeTests.cpp index 207b55dc8861..991e13b560fc 100644 --- a/generated/tests/ecr-public-gen-tests/ECRPublicIncludeTests.cpp +++ b/generated/tests/ecr-public-gen-tests/ECRPublicIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -26,12 +30,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/ecs-gen-tests/ECSIncludeTests.cpp b/generated/tests/ecs-gen-tests/ECSIncludeTests.cpp index 2054a4370f5c..53670be9047f 100644 --- a/generated/tests/ecs-gen-tests/ECSIncludeTests.cpp +++ b/generated/tests/ecs-gen-tests/ECSIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -242,12 +246,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -258,16 +266,21 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/eks-auth-gen-tests/EKSAuthIncludeTests.cpp b/generated/tests/eks-auth-gen-tests/EKSAuthIncludeTests.cpp index e8a1b5c45519..ca172b39928f 100644 --- a/generated/tests/eks-auth-gen-tests/EKSAuthIncludeTests.cpp +++ b/generated/tests/eks-auth-gen-tests/EKSAuthIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/eks-gen-tests/EKSIncludeTests.cpp b/generated/tests/eks-gen-tests/EKSIncludeTests.cpp index e69d5696ef24..b400702a3345 100644 --- a/generated/tests/eks-gen-tests/EKSIncludeTests.cpp +++ b/generated/tests/eks-gen-tests/EKSIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -131,12 +135,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -211,32 +217,45 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/elasticache-gen-tests/ElastiCacheIncludeTests.cpp b/generated/tests/elasticache-gen-tests/ElastiCacheIncludeTests.cpp index 0642bd0d5a1c..29ac92182e22 100644 --- a/generated/tests/elasticache-gen-tests/ElastiCacheIncludeTests.cpp +++ b/generated/tests/elasticache-gen-tests/ElastiCacheIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -100,42 +104,61 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/elasticbeanstalk-gen-tests/ElasticBeanstalkIncludeTests.cpp b/generated/tests/elasticbeanstalk-gen-tests/ElasticBeanstalkIncludeTests.cpp index 1ffe46eb9616..d29112c6ea51 100644 --- a/generated/tests/elasticbeanstalk-gen-tests/ElasticBeanstalkIncludeTests.cpp +++ b/generated/tests/elasticbeanstalk-gen-tests/ElasticBeanstalkIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -72,6 +76,7 @@ #include #include #include +#include #include #include #include @@ -80,6 +85,7 @@ #include #include #include +#include #include #include #include @@ -109,8 +115,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/elasticfilesystem-gen-tests/EFSIncludeTests.cpp b/generated/tests/elasticfilesystem-gen-tests/EFSIncludeTests.cpp index 7aa80ee915a1..e037ae0569ed 100644 --- a/generated/tests/elasticfilesystem-gen-tests/EFSIncludeTests.cpp +++ b/generated/tests/elasticfilesystem-gen-tests/EFSIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -37,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -45,14 +50,17 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include #include @@ -73,6 +81,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/elasticloadbalancing-gen-tests/ElasticLoadBalancingIncludeTests.cpp b/generated/tests/elasticloadbalancing-gen-tests/ElasticLoadBalancingIncludeTests.cpp index 4847e623987a..715e481d7b0b 100644 --- a/generated/tests/elasticloadbalancing-gen-tests/ElasticLoadBalancingIncludeTests.cpp +++ b/generated/tests/elasticloadbalancing-gen-tests/ElasticLoadBalancingIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -56,6 +60,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/elasticloadbalancingv2-gen-tests/ElasticLoadBalancingv2IncludeTests.cpp b/generated/tests/elasticloadbalancingv2-gen-tests/ElasticLoadBalancingv2IncludeTests.cpp index 68aa3e3c67e1..d838602093cb 100644 --- a/generated/tests/elasticloadbalancingv2-gen-tests/ElasticLoadBalancingv2IncludeTests.cpp +++ b/generated/tests/elasticloadbalancingv2-gen-tests/ElasticLoadBalancingv2IncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -58,20 +62,25 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include @@ -80,16 +89,20 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/elasticmapreduce-gen-tests/EMRIncludeTests.cpp b/generated/tests/elasticmapreduce-gen-tests/EMRIncludeTests.cpp index d2fe7a3006fb..73e4cc0cedcd 100644 --- a/generated/tests/elasticmapreduce-gen-tests/EMRIncludeTests.cpp +++ b/generated/tests/elasticmapreduce-gen-tests/EMRIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -152,30 +156,43 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/elementalinference-gen-tests/ElementalInferenceIncludeTests.cpp b/generated/tests/elementalinference-gen-tests/ElementalInferenceIncludeTests.cpp index df49f6554c83..4dc213e0d744 100644 --- a/generated/tests/elementalinference-gen-tests/ElementalInferenceIncludeTests.cpp +++ b/generated/tests/elementalinference-gen-tests/ElementalInferenceIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -47,8 +51,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -57,6 +63,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/email-gen-tests/SESIncludeTests.cpp b/generated/tests/email-gen-tests/SESIncludeTests.cpp index 40da2400a92c..43a3ce8305c9 100644 --- a/generated/tests/email-gen-tests/SESIncludeTests.cpp +++ b/generated/tests/email-gen-tests/SESIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -130,8 +134,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/emr-containers-gen-tests/EMRContainersIncludeTests.cpp b/generated/tests/emr-containers-gen-tests/EMRContainersIncludeTests.cpp index 1d1a71c1cd70..4057a3312b7f 100644 --- a/generated/tests/emr-containers-gen-tests/EMRContainersIncludeTests.cpp +++ b/generated/tests/emr-containers-gen-tests/EMRContainersIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -70,16 +74,21 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/emr-serverless-gen-tests/EMRServerlessIncludeTests.cpp b/generated/tests/emr-serverless-gen-tests/EMRServerlessIncludeTests.cpp index 5513659f98b1..e72f54ff20bf 100644 --- a/generated/tests/emr-serverless-gen-tests/EMRServerlessIncludeTests.cpp +++ b/generated/tests/emr-serverless-gen-tests/EMRServerlessIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -56,12 +60,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/entityresolution-gen-tests/EntityResolutionIncludeTests.cpp b/generated/tests/entityresolution-gen-tests/EntityResolutionIncludeTests.cpp index 2a13064ca9a4..495ff66d4a16 100644 --- a/generated/tests/entityresolution-gen-tests/EntityResolutionIncludeTests.cpp +++ b/generated/tests/entityresolution-gen-tests/EntityResolutionIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -89,18 +93,25 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/es-gen-tests/ElasticsearchServiceIncludeTests.cpp b/generated/tests/es-gen-tests/ElasticsearchServiceIncludeTests.cpp index 16487f0a9023..33914f63fb90 100644 --- a/generated/tests/es-gen-tests/ElasticsearchServiceIncludeTests.cpp +++ b/generated/tests/es-gen-tests/ElasticsearchServiceIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -77,6 +81,7 @@ #include #include #include +#include #include #include #include @@ -89,16 +94,21 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -133,8 +143,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -148,12 +160,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/eventbridge-gen-tests/EventBridgeIncludeTests.cpp b/generated/tests/eventbridge-gen-tests/EventBridgeIncludeTests.cpp index f5f99ffecf0e..9f015cce94a2 100644 --- a/generated/tests/eventbridge-gen-tests/EventBridgeIncludeTests.cpp +++ b/generated/tests/eventbridge-gen-tests/EventBridgeIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/events-gen-tests/CloudWatchEventsIncludeTests.cpp b/generated/tests/events-gen-tests/CloudWatchEventsIncludeTests.cpp index 599be83c420f..5505d4635acc 100644 --- a/generated/tests/events-gen-tests/CloudWatchEventsIncludeTests.cpp +++ b/generated/tests/events-gen-tests/CloudWatchEventsIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/evs-gen-tests/EVSIncludeTests.cpp b/generated/tests/evs-gen-tests/EVSIncludeTests.cpp index 3beb5cee02cd..82ff68873155 100644 --- a/generated/tests/evs-gen-tests/EVSIncludeTests.cpp +++ b/generated/tests/evs-gen-tests/EVSIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -62,16 +66,21 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/finspace-data-gen-tests/FinSpaceDataIncludeTests.cpp b/generated/tests/finspace-data-gen-tests/FinSpaceDataIncludeTests.cpp index d6dc185946d9..ae9dae892625 100644 --- a/generated/tests/finspace-data-gen-tests/FinSpaceDataIncludeTests.cpp +++ b/generated/tests/finspace-data-gen-tests/FinSpaceDataIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/finspace-gen-tests/FinspaceIncludeTests.cpp b/generated/tests/finspace-gen-tests/FinspaceIncludeTests.cpp index e9252f2b0941..820e6da9b92b 100644 --- a/generated/tests/finspace-gen-tests/FinspaceIncludeTests.cpp +++ b/generated/tests/finspace-gen-tests/FinspaceIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -115,18 +119,24 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/firehose-gen-tests/FirehoseIncludeTests.cpp b/generated/tests/firehose-gen-tests/FirehoseIncludeTests.cpp index d202da14450f..9b11383ace93 100644 --- a/generated/tests/firehose-gen-tests/FirehoseIncludeTests.cpp +++ b/generated/tests/firehose-gen-tests/FirehoseIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/fis-gen-tests/FISIncludeTests.cpp b/generated/tests/fis-gen-tests/FISIncludeTests.cpp index 93006218f7e4..17be9b97ec99 100644 --- a/generated/tests/fis-gen-tests/FISIncludeTests.cpp +++ b/generated/tests/fis-gen-tests/FISIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -94,20 +98,26 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/fms-gen-tests/FMSIncludeTests.cpp b/generated/tests/fms-gen-tests/FMSIncludeTests.cpp index 40bf34387094..a064e17b6556 100644 --- a/generated/tests/fms-gen-tests/FMSIncludeTests.cpp +++ b/generated/tests/fms-gen-tests/FMSIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -93,20 +97,27 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -115,6 +126,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/forecast-gen-tests/ForecastServiceIncludeTests.cpp b/generated/tests/forecast-gen-tests/ForecastServiceIncludeTests.cpp index b8860e6b6fd9..1fa6adc941a6 100644 --- a/generated/tests/forecast-gen-tests/ForecastServiceIncludeTests.cpp +++ b/generated/tests/forecast-gen-tests/ForecastServiceIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -125,34 +129,48 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/forecastquery-gen-tests/ForecastQueryServiceIncludeTests.cpp b/generated/tests/forecastquery-gen-tests/ForecastQueryServiceIncludeTests.cpp index ccd9d5fff00e..3d6586847b91 100644 --- a/generated/tests/forecastquery-gen-tests/ForecastQueryServiceIncludeTests.cpp +++ b/generated/tests/forecastquery-gen-tests/ForecastQueryServiceIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/frauddetector-gen-tests/FraudDetectorIncludeTests.cpp b/generated/tests/frauddetector-gen-tests/FraudDetectorIncludeTests.cpp index befdbc8e2fec..51ab41c1a4c3 100644 --- a/generated/tests/frauddetector-gen-tests/FraudDetectorIncludeTests.cpp +++ b/generated/tests/frauddetector-gen-tests/FraudDetectorIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -86,6 +90,7 @@ #include #include #include +#include #include #include #include @@ -109,16 +114,20 @@ #include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include #include @@ -127,26 +136,35 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -156,8 +174,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/freetier-gen-tests/FreeTierIncludeTests.cpp b/generated/tests/freetier-gen-tests/FreeTierIncludeTests.cpp index 402f9d7b9451..830153d1d4f9 100644 --- a/generated/tests/freetier-gen-tests/FreeTierIncludeTests.cpp +++ b/generated/tests/freetier-gen-tests/FreeTierIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -27,9 +31,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include diff --git a/generated/tests/fsx-gen-tests/FSxIncludeTests.cpp b/generated/tests/fsx-gen-tests/FSxIncludeTests.cpp index bc65a18e648f..6bc060964463 100644 --- a/generated/tests/fsx-gen-tests/FSxIncludeTests.cpp +++ b/generated/tests/fsx-gen-tests/FSxIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -117,26 +121,36 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -175,6 +189,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/gamelift-gen-tests/GameLiftIncludeTests.cpp b/generated/tests/gamelift-gen-tests/GameLiftIncludeTests.cpp index 3088bc6116f5..550b7a46e203 100644 --- a/generated/tests/gamelift-gen-tests/GameLiftIncludeTests.cpp +++ b/generated/tests/gamelift-gen-tests/GameLiftIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -137,14 +141,18 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include @@ -153,34 +161,44 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -254,29 +272,41 @@ #include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -338,6 +368,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/gameliftstreams-gen-tests/GameLiftStreamsIncludeTests.cpp b/generated/tests/gameliftstreams-gen-tests/GameLiftStreamsIncludeTests.cpp index ef9ba7c16e11..3616eb1ce09b 100644 --- a/generated/tests/gameliftstreams-gen-tests/GameLiftStreamsIncludeTests.cpp +++ b/generated/tests/gameliftstreams-gen-tests/GameLiftStreamsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -50,14 +54,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/geo-maps-gen-tests/GeoMapsIncludeTests.cpp b/generated/tests/geo-maps-gen-tests/GeoMapsIncludeTests.cpp index a6ede6cb2ea8..b90dcd4449da 100644 --- a/generated/tests/geo-maps-gen-tests/GeoMapsIncludeTests.cpp +++ b/generated/tests/geo-maps-gen-tests/GeoMapsIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/geo-places-gen-tests/GeoPlacesIncludeTests.cpp b/generated/tests/geo-places-gen-tests/GeoPlacesIncludeTests.cpp index 4b7fcd4df89a..97876a4027b9 100644 --- a/generated/tests/geo-places-gen-tests/GeoPlacesIncludeTests.cpp +++ b/generated/tests/geo-places-gen-tests/GeoPlacesIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/geo-routes-gen-tests/GeoRoutesIncludeTests.cpp b/generated/tests/geo-routes-gen-tests/GeoRoutesIncludeTests.cpp index 940aa3b993b4..0efb95f31c52 100644 --- a/generated/tests/geo-routes-gen-tests/GeoRoutesIncludeTests.cpp +++ b/generated/tests/geo-routes-gen-tests/GeoRoutesIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/glacier-gen-tests/GlacierIncludeTests.cpp b/generated/tests/glacier-gen-tests/GlacierIncludeTests.cpp index fe7d047cc164..d57f36532450 100644 --- a/generated/tests/glacier-gen-tests/GlacierIncludeTests.cpp +++ b/generated/tests/glacier-gen-tests/GlacierIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -66,16 +70,20 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/globalaccelerator-gen-tests/GlobalAcceleratorIncludeTests.cpp b/generated/tests/globalaccelerator-gen-tests/GlobalAcceleratorIncludeTests.cpp index 9dcc2b775e7d..fbae0d0471a3 100644 --- a/generated/tests/globalaccelerator-gen-tests/GlobalAcceleratorIncludeTests.cpp +++ b/generated/tests/globalaccelerator-gen-tests/GlobalAcceleratorIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -94,28 +98,39 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/glue-gen-tests/GlueIncludeTests.cpp b/generated/tests/glue-gen-tests/GlueIncludeTests.cpp index ddab605fde25..d17bd6b1abc2 100644 --- a/generated/tests/glue-gen-tests/GlueIncludeTests.cpp +++ b/generated/tests/glue-gen-tests/GlueIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -395,6 +399,7 @@ #include #include #include +#include #include #include #include @@ -478,6 +483,7 @@ #include #include #include +#include #include #include #include @@ -488,6 +494,7 @@ #include #include #include +#include #include #include #include @@ -496,6 +503,7 @@ #include #include #include +#include #include #include #include @@ -503,12 +511,15 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -533,12 +544,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -561,32 +574,39 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -601,6 +621,7 @@ #include #include #include +#include #include #include #include @@ -615,18 +636,22 @@ #include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -635,6 +660,7 @@ #include #include #include +#include #include #include #include @@ -643,6 +669,7 @@ #include #include #include +#include #include #include #include @@ -737,68 +764,95 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -977,6 +1031,7 @@ #include #include #include +#include #include #include #include @@ -988,6 +1043,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/grafana-gen-tests/ManagedGrafanaIncludeTests.cpp b/generated/tests/grafana-gen-tests/ManagedGrafanaIncludeTests.cpp index 0078755fd64b..7978c2f0eec5 100644 --- a/generated/tests/grafana-gen-tests/ManagedGrafanaIncludeTests.cpp +++ b/generated/tests/grafana-gen-tests/ManagedGrafanaIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -51,16 +55,21 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/greengrass-gen-tests/GreengrassIncludeTests.cpp b/generated/tests/greengrass-gen-tests/GreengrassIncludeTests.cpp index b10c440d3193..ed3156b627cb 100644 --- a/generated/tests/greengrass-gen-tests/GreengrassIncludeTests.cpp +++ b/generated/tests/greengrass-gen-tests/GreengrassIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/greengrassv2-gen-tests/GreengrassV2IncludeTests.cpp b/generated/tests/greengrassv2-gen-tests/GreengrassV2IncludeTests.cpp index 1fd4a368e6dc..0081e7318da3 100644 --- a/generated/tests/greengrassv2-gen-tests/GreengrassV2IncludeTests.cpp +++ b/generated/tests/greengrassv2-gen-tests/GreengrassV2IncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -102,18 +106,25 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/groundstation-gen-tests/GroundStationIncludeTests.cpp b/generated/tests/groundstation-gen-tests/GroundStationIncludeTests.cpp index ccd60743ccf2..cc7cd7939087 100644 --- a/generated/tests/groundstation-gen-tests/GroundStationIncludeTests.cpp +++ b/generated/tests/groundstation-gen-tests/GroundStationIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -127,24 +131,34 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/guardduty-gen-tests/GuardDutyIncludeTests.cpp b/generated/tests/guardduty-gen-tests/GuardDutyIncludeTests.cpp index 7ea300a01d5b..14be5371d5ed 100644 --- a/generated/tests/guardduty-gen-tests/GuardDutyIncludeTests.cpp +++ b/generated/tests/guardduty-gen-tests/GuardDutyIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -132,8 +136,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -239,6 +245,7 @@ #include #include #include +#include #include #include #include @@ -283,18 +290,25 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -302,20 +316,27 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/health-gen-tests/HealthIncludeTests.cpp b/generated/tests/health-gen-tests/HealthIncludeTests.cpp index 382aaf7d0b2c..65f95dd2403e 100644 --- a/generated/tests/health-gen-tests/HealthIncludeTests.cpp +++ b/generated/tests/health-gen-tests/HealthIncludeTests.cpp @@ -7,35 +7,46 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/healthlake-gen-tests/HealthLakeIncludeTests.cpp b/generated/tests/healthlake-gen-tests/HealthLakeIncludeTests.cpp index f5674c399c76..5ad02ae16214 100644 --- a/generated/tests/healthlake-gen-tests/HealthLakeIncludeTests.cpp +++ b/generated/tests/healthlake-gen-tests/HealthLakeIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -57,16 +61,22 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/iam-gen-tests/IAMIncludeTests.cpp b/generated/tests/iam-gen-tests/IAMIncludeTests.cpp index 39af713bf81a..1e19180cd3c3 100644 --- a/generated/tests/iam-gen-tests/IAMIncludeTests.cpp +++ b/generated/tests/iam-gen-tests/IAMIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -124,6 +128,7 @@ #include #include #include +#include #include #include #include @@ -140,6 +145,7 @@ #include #include #include +#include #include #include #include @@ -191,36 +197,51 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -230,38 +251,53 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -333,8 +369,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/identitystore-gen-tests/IdentityStoreIncludeTests.cpp b/generated/tests/identitystore-gen-tests/IdentityStoreIncludeTests.cpp index 5d9863a6c540..3abe4db3f5cf 100644 --- a/generated/tests/identitystore-gen-tests/IdentityStoreIncludeTests.cpp +++ b/generated/tests/identitystore-gen-tests/IdentityStoreIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -53,12 +57,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/imagebuilder-gen-tests/ImagebuilderIncludeTests.cpp b/generated/tests/imagebuilder-gen-tests/ImagebuilderIncludeTests.cpp index bd3352f5dc34..ea825b1d7b1d 100644 --- a/generated/tests/imagebuilder-gen-tests/ImagebuilderIncludeTests.cpp +++ b/generated/tests/imagebuilder-gen-tests/ImagebuilderIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -187,48 +191,69 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/importexport-gen-tests/ImportExportIncludeTests.cpp b/generated/tests/importexport-gen-tests/ImportExportIncludeTests.cpp index eec8e2e5c086..081cd31a0802 100644 --- a/generated/tests/importexport-gen-tests/ImportExportIncludeTests.cpp +++ b/generated/tests/importexport-gen-tests/ImportExportIncludeTests.cpp @@ -10,8 +10,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/inspector-gen-tests/InspectorIncludeTests.cpp b/generated/tests/inspector-gen-tests/InspectorIncludeTests.cpp index 2bb49bd87aef..6ec0fada2f5f 100644 --- a/generated/tests/inspector-gen-tests/InspectorIncludeTests.cpp +++ b/generated/tests/inspector-gen-tests/InspectorIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -75,6 +79,7 @@ #include #include #include +#include #include #include #include @@ -88,20 +93,28 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -110,6 +123,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/inspector-scan-gen-tests/InspectorscanIncludeTests.cpp b/generated/tests/inspector-scan-gen-tests/InspectorscanIncludeTests.cpp index 019575136d62..b9d2a4a8a0e3 100644 --- a/generated/tests/inspector-scan-gen-tests/InspectorscanIncludeTests.cpp +++ b/generated/tests/inspector-scan-gen-tests/InspectorscanIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/inspector2-gen-tests/Inspector2IncludeTests.cpp b/generated/tests/inspector2-gen-tests/Inspector2IncludeTests.cpp index a7cc5122a93d..5d8e6fdc6523 100644 --- a/generated/tests/inspector2-gen-tests/Inspector2IncludeTests.cpp +++ b/generated/tests/inspector2-gen-tests/Inspector2IncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -276,8 +280,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -318,17 +324,22 @@ #include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -338,26 +349,36 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -430,6 +451,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/interconnect-gen-tests/InterconnectIncludeTests.cpp b/generated/tests/interconnect-gen-tests/InterconnectIncludeTests.cpp index 7a9033332c07..38d8294dde00 100644 --- a/generated/tests/interconnect-gen-tests/InterconnectIncludeTests.cpp +++ b/generated/tests/interconnect-gen-tests/InterconnectIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -34,10 +38,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/internetmonitor-gen-tests/InternetMonitorIncludeTests.cpp b/generated/tests/internetmonitor-gen-tests/InternetMonitorIncludeTests.cpp index 5bf128b857a5..8b607c4d4975 100644 --- a/generated/tests/internetmonitor-gen-tests/InternetMonitorIncludeTests.cpp +++ b/generated/tests/internetmonitor-gen-tests/InternetMonitorIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -26,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -40,10 +45,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/invoicing-gen-tests/InvoicingIncludeTests.cpp b/generated/tests/invoicing-gen-tests/InvoicingIncludeTests.cpp index 2eca3b71a831..a044b9c86b9d 100644 --- a/generated/tests/invoicing-gen-tests/InvoicingIncludeTests.cpp +++ b/generated/tests/invoicing-gen-tests/InvoicingIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -61,11 +65,14 @@ #include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/iot-data-gen-tests/IoTDataPlaneIncludeTests.cpp b/generated/tests/iot-data-gen-tests/IoTDataPlaneIncludeTests.cpp index 2fb8bfed8e99..cbcbef41518d 100644 --- a/generated/tests/iot-data-gen-tests/IoTDataPlaneIncludeTests.cpp +++ b/generated/tests/iot-data-gen-tests/IoTDataPlaneIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -24,8 +28,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/iot-gen-tests/IoTIncludeTests.cpp b/generated/tests/iot-gen-tests/IoTIncludeTests.cpp index b1fd19a882a0..2e8847674bb9 100644 --- a/generated/tests/iot-gen-tests/IoTIncludeTests.cpp +++ b/generated/tests/iot-gen-tests/IoTIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -391,6 +395,7 @@ #include #include #include +#include #include #include #include @@ -470,130 +475,191 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/iot-jobs-data-gen-tests/IoTJobsDataPlaneIncludeTests.cpp b/generated/tests/iot-jobs-data-gen-tests/IoTJobsDataPlaneIncludeTests.cpp index 06aad2e4e13e..7166755e4402 100644 --- a/generated/tests/iot-jobs-data-gen-tests/IoTJobsDataPlaneIncludeTests.cpp +++ b/generated/tests/iot-jobs-data-gen-tests/IoTJobsDataPlaneIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/iot-managed-integrations-gen-tests/IoTManagedIntegrationsIncludeTests.cpp b/generated/tests/iot-managed-integrations-gen-tests/IoTManagedIntegrationsIncludeTests.cpp index 3fdb2acdd7e9..89e952fb1f36 100644 --- a/generated/tests/iot-managed-integrations-gen-tests/IoTManagedIntegrationsIncludeTests.cpp +++ b/generated/tests/iot-managed-integrations-gen-tests/IoTManagedIntegrationsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -136,38 +140,55 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/iotdeviceadvisor-gen-tests/IoTDeviceAdvisorIncludeTests.cpp b/generated/tests/iotdeviceadvisor-gen-tests/IoTDeviceAdvisorIncludeTests.cpp index 58b40c22da39..cf25d8c4c7a4 100644 --- a/generated/tests/iotdeviceadvisor-gen-tests/IoTDeviceAdvisorIncludeTests.cpp +++ b/generated/tests/iotdeviceadvisor-gen-tests/IoTDeviceAdvisorIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -28,8 +32,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/iotfleetwise-gen-tests/IoTFleetWiseIncludeTests.cpp b/generated/tests/iotfleetwise-gen-tests/IoTFleetWiseIncludeTests.cpp index 6e102a29c9ff..1faad3b58465 100644 --- a/generated/tests/iotfleetwise-gen-tests/IoTFleetWiseIncludeTests.cpp +++ b/generated/tests/iotfleetwise-gen-tests/IoTFleetWiseIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -103,6 +107,7 @@ #include #include #include +#include #include #include #include @@ -118,33 +123,46 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/iotsecuretunneling-gen-tests/IoTSecureTunnelingIncludeTests.cpp b/generated/tests/iotsecuretunneling-gen-tests/IoTSecureTunnelingIncludeTests.cpp index 3fbb00e633fa..c7e739e66b11 100644 --- a/generated/tests/iotsecuretunneling-gen-tests/IoTSecureTunnelingIncludeTests.cpp +++ b/generated/tests/iotsecuretunneling-gen-tests/IoTSecureTunnelingIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -23,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/iotsitewise-gen-tests/IoTSiteWiseIncludeTests.cpp b/generated/tests/iotsitewise-gen-tests/IoTSiteWiseIncludeTests.cpp index 4e241e629ce5..5a5fc09202d1 100644 --- a/generated/tests/iotsitewise-gen-tests/IoTSiteWiseIncludeTests.cpp +++ b/generated/tests/iotsitewise-gen-tests/IoTSiteWiseIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -82,6 +86,7 @@ #include #include #include +#include #include #include #include @@ -94,10 +99,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -278,6 +285,7 @@ #include #include #include +#include #include #include #include @@ -318,6 +326,7 @@ #include #include #include +#include #include #include #include @@ -339,18 +348,23 @@ #include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -378,80 +392,114 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include diff --git a/generated/tests/iotthingsgraph-gen-tests/IoTThingsGraphIncludeTests.cpp b/generated/tests/iotthingsgraph-gen-tests/IoTThingsGraphIncludeTests.cpp index 32a13d6353e9..6b435359096f 100644 --- a/generated/tests/iotthingsgraph-gen-tests/IoTThingsGraphIncludeTests.cpp +++ b/generated/tests/iotthingsgraph-gen-tests/IoTThingsGraphIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/iottwinmaker-gen-tests/IoTTwinMakerIncludeTests.cpp b/generated/tests/iottwinmaker-gen-tests/IoTTwinMakerIncludeTests.cpp index 11b1d4baec3a..428263e81a73 100644 --- a/generated/tests/iottwinmaker-gen-tests/IoTTwinMakerIncludeTests.cpp +++ b/generated/tests/iottwinmaker-gen-tests/IoTTwinMakerIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -65,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -81,8 +86,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -101,26 +108,35 @@ #include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/iotwireless-gen-tests/IoTWirelessIncludeTests.cpp b/generated/tests/iotwireless-gen-tests/IoTWirelessIncludeTests.cpp index dda052b29ff8..d5032d78a15b 100644 --- a/generated/tests/iotwireless-gen-tests/IoTWirelessIncludeTests.cpp +++ b/generated/tests/iotwireless-gen-tests/IoTWirelessIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -200,36 +204,46 @@ #include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/ivs-gen-tests/IVSIncludeTests.cpp b/generated/tests/ivs-gen-tests/IVSIncludeTests.cpp index 86fb09298a28..f108d204bded 100644 --- a/generated/tests/ivs-gen-tests/IVSIncludeTests.cpp +++ b/generated/tests/ivs-gen-tests/IVSIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -74,20 +78,28 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/ivs-realtime-gen-tests/IvsrealtimeIncludeTests.cpp b/generated/tests/ivs-realtime-gen-tests/IvsrealtimeIncludeTests.cpp index c74261496709..3e2ce1850964 100644 --- a/generated/tests/ivs-realtime-gen-tests/IvsrealtimeIncludeTests.cpp +++ b/generated/tests/ivs-realtime-gen-tests/IvsrealtimeIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -80,24 +84,34 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/ivschat-gen-tests/IvschatIncludeTests.cpp b/generated/tests/ivschat-gen-tests/IvschatIncludeTests.cpp index a56036fe6118..0603bef02d98 100644 --- a/generated/tests/ivschat-gen-tests/IvschatIncludeTests.cpp +++ b/generated/tests/ivschat-gen-tests/IvschatIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -36,8 +40,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/kafka-gen-tests/KafkaIncludeTests.cpp b/generated/tests/kafka-gen-tests/KafkaIncludeTests.cpp index 490287a3b78b..e2937c6e86df 100644 --- a/generated/tests/kafka-gen-tests/KafkaIncludeTests.cpp +++ b/generated/tests/kafka-gen-tests/KafkaIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -108,6 +112,7 @@ #include #include #include +#include #include #include #include @@ -154,32 +159,45 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/kafkaconnect-gen-tests/KafkaConnectIncludeTests.cpp b/generated/tests/kafkaconnect-gen-tests/KafkaConnectIncludeTests.cpp index b205b6b49981..f4d78fab4756 100644 --- a/generated/tests/kafkaconnect-gen-tests/KafkaConnectIncludeTests.cpp +++ b/generated/tests/kafkaconnect-gen-tests/KafkaConnectIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -70,14 +74,18 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/kendra-gen-tests/KendraIncludeTests.cpp b/generated/tests/kendra-gen-tests/KendraIncludeTests.cpp index 0402c0e114ab..63934ab295d2 100644 --- a/generated/tests/kendra-gen-tests/KendraIncludeTests.cpp +++ b/generated/tests/kendra-gen-tests/KendraIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -179,6 +183,7 @@ #include #include #include +#include #include #include #include @@ -202,30 +207,41 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/kendra-ranking-gen-tests/KendraRankingIncludeTests.cpp b/generated/tests/kendra-ranking-gen-tests/KendraRankingIncludeTests.cpp index c83ac321891c..7648ed09b556 100644 --- a/generated/tests/kendra-ranking-gen-tests/KendraRankingIncludeTests.cpp +++ b/generated/tests/kendra-ranking-gen-tests/KendraRankingIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -20,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/keyspaces-gen-tests/KeyspacesIncludeTests.cpp b/generated/tests/keyspaces-gen-tests/KeyspacesIncludeTests.cpp index 1a92fd46fa99..7e3baa75db02 100644 --- a/generated/tests/keyspaces-gen-tests/KeyspacesIncludeTests.cpp +++ b/generated/tests/keyspaces-gen-tests/KeyspacesIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -52,12 +56,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/keyspacesstreams-gen-tests/KeyspacesStreamsIncludeTests.cpp b/generated/tests/keyspacesstreams-gen-tests/KeyspacesStreamsIncludeTests.cpp index 716b8c55ac8d..3e59d8802f37 100644 --- a/generated/tests/keyspacesstreams-gen-tests/KeyspacesStreamsIncludeTests.cpp +++ b/generated/tests/keyspacesstreams-gen-tests/KeyspacesStreamsIncludeTests.cpp @@ -7,16 +7,21 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include #include +#include #include #include #include @@ -26,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/kinesis-gen-tests/KinesisIncludeTests.cpp b/generated/tests/kinesis-gen-tests/KinesisIncludeTests.cpp index 56011624bc93..c3753761266e 100644 --- a/generated/tests/kinesis-gen-tests/KinesisIncludeTests.cpp +++ b/generated/tests/kinesis-gen-tests/KinesisIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -49,8 +53,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/kinesis-video-archived-media-gen-tests/KinesisVideoArchivedMediaIncludeTests.cpp b/generated/tests/kinesis-video-archived-media-gen-tests/KinesisVideoArchivedMediaIncludeTests.cpp index 9bba711e1cb4..38e9745d235d 100644 --- a/generated/tests/kinesis-video-archived-media-gen-tests/KinesisVideoArchivedMediaIncludeTests.cpp +++ b/generated/tests/kinesis-video-archived-media-gen-tests/KinesisVideoArchivedMediaIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -34,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +52,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/kinesis-video-media-gen-tests/KinesisVideoMediaIncludeTests.cpp b/generated/tests/kinesis-video-media-gen-tests/KinesisVideoMediaIncludeTests.cpp index 69bb6bd309b2..f2d519b7189c 100644 --- a/generated/tests/kinesis-video-media-gen-tests/KinesisVideoMediaIncludeTests.cpp +++ b/generated/tests/kinesis-video-media-gen-tests/KinesisVideoMediaIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/kinesis-video-signaling-gen-tests/KinesisVideoSignalingChannelsIncludeTests.cpp b/generated/tests/kinesis-video-signaling-gen-tests/KinesisVideoSignalingChannelsIncludeTests.cpp index 3025063647e4..0dfa6183bcc9 100644 --- a/generated/tests/kinesis-video-signaling-gen-tests/KinesisVideoSignalingChannelsIncludeTests.cpp +++ b/generated/tests/kinesis-video-signaling-gen-tests/KinesisVideoSignalingChannelsIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/kinesis-video-webrtc-storage-gen-tests/KinesisVideoWebRTCStorageIncludeTests.cpp b/generated/tests/kinesis-video-webrtc-storage-gen-tests/KinesisVideoWebRTCStorageIncludeTests.cpp index d70ab99b03d6..afc80349d465 100644 --- a/generated/tests/kinesis-video-webrtc-storage-gen-tests/KinesisVideoWebRTCStorageIncludeTests.cpp +++ b/generated/tests/kinesis-video-webrtc-storage-gen-tests/KinesisVideoWebRTCStorageIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include diff --git a/generated/tests/kinesisanalytics-gen-tests/KinesisAnalyticsIncludeTests.cpp b/generated/tests/kinesisanalytics-gen-tests/KinesisAnalyticsIncludeTests.cpp index ea9fab773394..643929e3cd50 100644 --- a/generated/tests/kinesisanalytics-gen-tests/KinesisAnalyticsIncludeTests.cpp +++ b/generated/tests/kinesisanalytics-gen-tests/KinesisAnalyticsIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/kinesisanalyticsv2-gen-tests/KinesisAnalyticsV2IncludeTests.cpp b/generated/tests/kinesisanalyticsv2-gen-tests/KinesisAnalyticsV2IncludeTests.cpp index 42ef55bf5f80..d4ad5b97ebd7 100644 --- a/generated/tests/kinesisanalyticsv2-gen-tests/KinesisAnalyticsV2IncludeTests.cpp +++ b/generated/tests/kinesisanalyticsv2-gen-tests/KinesisAnalyticsV2IncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -146,12 +150,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/kinesisvideo-gen-tests/KinesisVideoIncludeTests.cpp b/generated/tests/kinesisvideo-gen-tests/KinesisVideoIncludeTests.cpp index 5ba79307e30b..1161fa716803 100644 --- a/generated/tests/kinesisvideo-gen-tests/KinesisVideoIncludeTests.cpp +++ b/generated/tests/kinesisvideo-gen-tests/KinesisVideoIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -37,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -63,10 +68,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/kms-gen-tests/KMSIncludeTests.cpp b/generated/tests/kms-gen-tests/KMSIncludeTests.cpp index 7526b6953744..858a566a0936 100644 --- a/generated/tests/kms-gen-tests/KMSIncludeTests.cpp +++ b/generated/tests/kms-gen-tests/KMSIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -41,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -97,18 +102,25 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/lakeformation-gen-tests/LakeFormationIncludeTests.cpp b/generated/tests/lakeformation-gen-tests/LakeFormationIncludeTests.cpp index 4d50f40bf4af..65991aef62df 100644 --- a/generated/tests/lakeformation-gen-tests/LakeFormationIncludeTests.cpp +++ b/generated/tests/lakeformation-gen-tests/LakeFormationIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -90,6 +94,7 @@ #include #include #include +#include #include #include #include @@ -102,6 +107,7 @@ #include #include #include +#include #include #include #include @@ -112,6 +118,7 @@ #include #include #include +#include #include #include #include @@ -124,20 +131,28 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -166,8 +181,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/lambda-core-gen-tests/LambdaCoreIncludeTests.cpp b/generated/tests/lambda-core-gen-tests/LambdaCoreIncludeTests.cpp index 024bdde052df..b3121c1e27ee 100644 --- a/generated/tests/lambda-core-gen-tests/LambdaCoreIncludeTests.cpp +++ b/generated/tests/lambda-core-gen-tests/LambdaCoreIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -21,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/lambda-gen-tests/LambdaIncludeTests.cpp b/generated/tests/lambda-gen-tests/LambdaIncludeTests.cpp index 2a9ea336f362..a36346ca7fa4 100644 --- a/generated/tests/lambda-gen-tests/LambdaIncludeTests.cpp +++ b/generated/tests/lambda-gen-tests/LambdaIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -162,10 +166,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -237,34 +243,48 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/lambda-microvms-gen-tests/LambdaMicrovmsIncludeTests.cpp b/generated/tests/lambda-microvms-gen-tests/LambdaMicrovmsIncludeTests.cpp index 7cc91972dfff..502c60d265b3 100644 --- a/generated/tests/lambda-microvms-gen-tests/LambdaMicrovmsIncludeTests.cpp +++ b/generated/tests/lambda-microvms-gen-tests/LambdaMicrovmsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -44,16 +48,22 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/launch-wizard-gen-tests/LaunchWizardIncludeTests.cpp b/generated/tests/launch-wizard-gen-tests/LaunchWizardIncludeTests.cpp index bd72ade33dbf..17e881df87af 100644 --- a/generated/tests/launch-wizard-gen-tests/LaunchWizardIncludeTests.cpp +++ b/generated/tests/launch-wizard-gen-tests/LaunchWizardIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -37,16 +41,21 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/lex-gen-tests/LexRuntimeServiceIncludeTests.cpp b/generated/tests/lex-gen-tests/LexRuntimeServiceIncludeTests.cpp index 3db9cdb53fd9..051245760ef1 100644 --- a/generated/tests/lex-gen-tests/LexRuntimeServiceIncludeTests.cpp +++ b/generated/tests/lex-gen-tests/LexRuntimeServiceIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/lex-models-gen-tests/LexModelBuildingServiceIncludeTests.cpp b/generated/tests/lex-models-gen-tests/LexModelBuildingServiceIncludeTests.cpp index 1d9b7ede95ce..aec220e1ca8e 100644 --- a/generated/tests/lex-models-gen-tests/LexModelBuildingServiceIncludeTests.cpp +++ b/generated/tests/lex-models-gen-tests/LexModelBuildingServiceIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/lexv2-models-gen-tests/LexModelsV2IncludeTests.cpp b/generated/tests/lexv2-models-gen-tests/LexModelsV2IncludeTests.cpp index b827b78dcd4f..1e14b0f9437b 100644 --- a/generated/tests/lexv2-models-gen-tests/LexModelsV2IncludeTests.cpp +++ b/generated/tests/lexv2-models-gen-tests/LexModelsV2IncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -240,6 +244,7 @@ #include #include #include +#include #include #include #include @@ -350,68 +355,97 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/lexv2-runtime-gen-tests/LexRuntimeV2IncludeTests.cpp b/generated/tests/lexv2-runtime-gen-tests/LexRuntimeV2IncludeTests.cpp index ecc7d11718e2..3939cfdd16fd 100644 --- a/generated/tests/lexv2-runtime-gen-tests/LexRuntimeV2IncludeTests.cpp +++ b/generated/tests/lexv2-runtime-gen-tests/LexRuntimeV2IncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/license-manager-gen-tests/LicenseManagerIncludeTests.cpp b/generated/tests/license-manager-gen-tests/LicenseManagerIncludeTests.cpp index cbd237f7d4ea..13373de55d3f 100644 --- a/generated/tests/license-manager-gen-tests/LicenseManagerIncludeTests.cpp +++ b/generated/tests/license-manager-gen-tests/LicenseManagerIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/license-manager-linux-subscriptions-gen-tests/LicenseManagerLinuxSubscriptionsIncludeTests.cpp b/generated/tests/license-manager-linux-subscriptions-gen-tests/LicenseManagerLinuxSubscriptionsIncludeTests.cpp index 634523256fe0..a134ac3b3ed6 100644 --- a/generated/tests/license-manager-linux-subscriptions-gen-tests/LicenseManagerLinuxSubscriptionsIncludeTests.cpp +++ b/generated/tests/license-manager-linux-subscriptions-gen-tests/LicenseManagerLinuxSubscriptionsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -23,10 +27,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/license-manager-user-subscriptions-gen-tests/LicenseManagerUserSubscriptionsIncludeTests.cpp b/generated/tests/license-manager-user-subscriptions-gen-tests/LicenseManagerUserSubscriptionsIncludeTests.cpp index a8c8747fdfe0..55646f784ae6 100644 --- a/generated/tests/license-manager-user-subscriptions-gen-tests/LicenseManagerUserSubscriptionsIncludeTests.cpp +++ b/generated/tests/license-manager-user-subscriptions-gen-tests/LicenseManagerUserSubscriptionsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -38,16 +42,21 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/lightsail-gen-tests/LightsailIncludeTests.cpp b/generated/tests/lightsail-gen-tests/LightsailIncludeTests.cpp index 9fda76871fa2..06935b1d9acf 100644 --- a/generated/tests/lightsail-gen-tests/LightsailIncludeTests.cpp +++ b/generated/tests/lightsail-gen-tests/LightsailIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/location-gen-tests/LocationServiceIncludeTests.cpp b/generated/tests/location-gen-tests/LocationServiceIncludeTests.cpp index 8e010d211d5d..ef0528e9f338 100644 --- a/generated/tests/location-gen-tests/LocationServiceIncludeTests.cpp +++ b/generated/tests/location-gen-tests/LocationServiceIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -98,11 +102,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -135,34 +141,44 @@ #include #include #include +#include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/logs-gen-tests/CloudWatchLogsIncludeTests.cpp b/generated/tests/logs-gen-tests/CloudWatchLogsIncludeTests.cpp index 89894d403c2d..801b0a27c0ab 100644 --- a/generated/tests/logs-gen-tests/CloudWatchLogsIncludeTests.cpp +++ b/generated/tests/logs-gen-tests/CloudWatchLogsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -88,14 +92,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -108,12 +117,15 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -122,6 +134,7 @@ #include #include #include +#include #include #include #include @@ -141,6 +154,7 @@ #include #include #include +#include #include #include #include @@ -159,6 +173,7 @@ #include #include #include +#include #include #include #include @@ -175,6 +190,7 @@ #include #include #include +#include #include #include #include @@ -202,20 +218,26 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/lookoutequipment-gen-tests/LookoutEquipmentIncludeTests.cpp b/generated/tests/lookoutequipment-gen-tests/LookoutEquipmentIncludeTests.cpp index 8bed3af2303a..aca2d551b95d 100644 --- a/generated/tests/lookoutequipment-gen-tests/LookoutEquipmentIncludeTests.cpp +++ b/generated/tests/lookoutequipment-gen-tests/LookoutEquipmentIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -89,26 +93,37 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/m2-gen-tests/MainframeModernizationIncludeTests.cpp b/generated/tests/m2-gen-tests/MainframeModernizationIncludeTests.cpp index 59c9d7bca593..f8cd6cc69775 100644 --- a/generated/tests/m2-gen-tests/MainframeModernizationIncludeTests.cpp +++ b/generated/tests/m2-gen-tests/MainframeModernizationIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -94,26 +98,36 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/machinelearning-gen-tests/MachineLearningIncludeTests.cpp b/generated/tests/machinelearning-gen-tests/MachineLearningIncludeTests.cpp index afd6a8fd4530..e15192ea1731 100644 --- a/generated/tests/machinelearning-gen-tests/MachineLearningIncludeTests.cpp +++ b/generated/tests/machinelearning-gen-tests/MachineLearningIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -46,12 +50,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/macie2-gen-tests/Macie2IncludeTests.cpp b/generated/tests/macie2-gen-tests/Macie2IncludeTests.cpp index f5045bc9a74c..6d213134c18d 100644 --- a/generated/tests/macie2-gen-tests/Macie2IncludeTests.cpp +++ b/generated/tests/macie2-gen-tests/Macie2IncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -103,6 +107,7 @@ #include #include #include +#include #include #include #include @@ -182,6 +187,7 @@ #include #include #include +#include #include #include #include @@ -208,20 +214,28 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -229,16 +243,22 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -291,6 +311,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/mailmanager-gen-tests/MailManagerIncludeTests.cpp b/generated/tests/mailmanager-gen-tests/MailManagerIncludeTests.cpp index ceeb2699c0e1..f0bd3dd9eb06 100644 --- a/generated/tests/mailmanager-gen-tests/MailManagerIncludeTests.cpp +++ b/generated/tests/mailmanager-gen-tests/MailManagerIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -146,30 +150,42 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/managedblockchain-gen-tests/ManagedBlockchainIncludeTests.cpp b/generated/tests/managedblockchain-gen-tests/ManagedBlockchainIncludeTests.cpp index 46fce1cdb5c8..275a272fac2e 100644 --- a/generated/tests/managedblockchain-gen-tests/ManagedBlockchainIncludeTests.cpp +++ b/generated/tests/managedblockchain-gen-tests/ManagedBlockchainIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -50,18 +54,25 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/managedblockchain-query-gen-tests/ManagedBlockchainQueryIncludeTests.cpp b/generated/tests/managedblockchain-query-gen-tests/ManagedBlockchainQueryIncludeTests.cpp index 58e924da54ee..95053d7d5fcb 100644 --- a/generated/tests/managedblockchain-query-gen-tests/ManagedBlockchainQueryIncludeTests.cpp +++ b/generated/tests/managedblockchain-query-gen-tests/ManagedBlockchainQueryIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -35,16 +39,21 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/marketplace-agreement-gen-tests/AgreementServiceIncludeTests.cpp b/generated/tests/marketplace-agreement-gen-tests/AgreementServiceIncludeTests.cpp index b3b9a2085d39..6c64dc38539f 100644 --- a/generated/tests/marketplace-agreement-gen-tests/AgreementServiceIncludeTests.cpp +++ b/generated/tests/marketplace-agreement-gen-tests/AgreementServiceIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -70,10 +74,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -87,14 +93,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -120,6 +131,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/marketplace-catalog-gen-tests/MarketplaceCatalogIncludeTests.cpp b/generated/tests/marketplace-catalog-gen-tests/MarketplaceCatalogIncludeTests.cpp index 12e53e3c0be8..7c45e338933d 100644 --- a/generated/tests/marketplace-catalog-gen-tests/MarketplaceCatalogIncludeTests.cpp +++ b/generated/tests/marketplace-catalog-gen-tests/MarketplaceCatalogIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -70,8 +74,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/marketplace-deployment-gen-tests/MarketplaceDeploymentIncludeTests.cpp b/generated/tests/marketplace-deployment-gen-tests/MarketplaceDeploymentIncludeTests.cpp index f6d3c07ce3ac..598aeecb8b6f 100644 --- a/generated/tests/marketplace-deployment-gen-tests/MarketplaceDeploymentIncludeTests.cpp +++ b/generated/tests/marketplace-deployment-gen-tests/MarketplaceDeploymentIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/marketplace-discovery-gen-tests/MarketplaceDiscoveryIncludeTests.cpp b/generated/tests/marketplace-discovery-gen-tests/MarketplaceDiscoveryIncludeTests.cpp index 514c755fb713..674a0732e551 100644 --- a/generated/tests/marketplace-discovery-gen-tests/MarketplaceDiscoveryIncludeTests.cpp +++ b/generated/tests/marketplace-discovery-gen-tests/MarketplaceDiscoveryIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -47,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -56,8 +61,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -106,10 +113,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/marketplace-entitlement-gen-tests/MarketplaceEntitlementServiceIncludeTests.cpp b/generated/tests/marketplace-entitlement-gen-tests/MarketplaceEntitlementServiceIncludeTests.cpp index a9902953683a..3003451f2add 100644 --- a/generated/tests/marketplace-entitlement-gen-tests/MarketplaceEntitlementServiceIncludeTests.cpp +++ b/generated/tests/marketplace-entitlement-gen-tests/MarketplaceEntitlementServiceIncludeTests.cpp @@ -7,15 +7,20 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include +#include #include #include diff --git a/generated/tests/marketplace-reporting-gen-tests/MarketplaceReportingIncludeTests.cpp b/generated/tests/marketplace-reporting-gen-tests/MarketplaceReportingIncludeTests.cpp index 76da2931f6b9..1ecc6365207f 100644 --- a/generated/tests/marketplace-reporting-gen-tests/MarketplaceReportingIncludeTests.cpp +++ b/generated/tests/marketplace-reporting-gen-tests/MarketplaceReportingIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include diff --git a/generated/tests/marketplacecommerceanalytics-gen-tests/MarketplaceCommerceAnalyticsIncludeTests.cpp b/generated/tests/marketplacecommerceanalytics-gen-tests/MarketplaceCommerceAnalyticsIncludeTests.cpp index 4ea892979e6a..58294c2a8ef7 100644 --- a/generated/tests/marketplacecommerceanalytics-gen-tests/MarketplaceCommerceAnalyticsIncludeTests.cpp +++ b/generated/tests/marketplacecommerceanalytics-gen-tests/MarketplaceCommerceAnalyticsIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/mediaconnect-gen-tests/MediaConnectIncludeTests.cpp b/generated/tests/mediaconnect-gen-tests/MediaConnectIncludeTests.cpp index 6b77e2572f2c..dfbdc835c787 100644 --- a/generated/tests/mediaconnect-gen-tests/MediaConnectIncludeTests.cpp +++ b/generated/tests/mediaconnect-gen-tests/MediaConnectIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -165,24 +169,34 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/mediaconvert-gen-tests/MediaConvertIncludeTests.cpp b/generated/tests/mediaconvert-gen-tests/MediaConvertIncludeTests.cpp index 97fe3c73fff7..1ba94a8f9caf 100644 --- a/generated/tests/mediaconvert-gen-tests/MediaConvertIncludeTests.cpp +++ b/generated/tests/mediaconvert-gen-tests/MediaConvertIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -456,16 +460,21 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -637,6 +646,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/medialive-gen-tests/MediaLiveIncludeTests.cpp b/generated/tests/medialive-gen-tests/MediaLiveIncludeTests.cpp index 7100543f9adc..e1ebb33ba8a4 100644 --- a/generated/tests/medialive-gen-tests/MediaLiveIncludeTests.cpp +++ b/generated/tests/medialive-gen-tests/MediaLiveIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -273,6 +277,7 @@ #include #include #include +#include #include #include #include @@ -542,48 +547,70 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/mediapackage-gen-tests/MediaPackageIncludeTests.cpp b/generated/tests/mediapackage-gen-tests/MediaPackageIncludeTests.cpp index 6d82238e8917..966bc3b64398 100644 --- a/generated/tests/mediapackage-gen-tests/MediaPackageIncludeTests.cpp +++ b/generated/tests/mediapackage-gen-tests/MediaPackageIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -52,10 +56,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/mediapackage-vod-gen-tests/MediaPackageVodIncludeTests.cpp b/generated/tests/mediapackage-vod-gen-tests/MediaPackageVodIncludeTests.cpp index a06faf5bb2d4..6d8d14b27e77 100644 --- a/generated/tests/mediapackage-vod-gen-tests/MediaPackageVodIncludeTests.cpp +++ b/generated/tests/mediapackage-vod-gen-tests/MediaPackageVodIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -48,10 +52,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/mediapackagev2-gen-tests/Mediapackagev2IncludeTests.cpp b/generated/tests/mediapackagev2-gen-tests/Mediapackagev2IncludeTests.cpp index a4f2ec67d1a8..93face61e902 100644 --- a/generated/tests/mediapackagev2-gen-tests/Mediapackagev2IncludeTests.cpp +++ b/generated/tests/mediapackagev2-gen-tests/Mediapackagev2IncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -99,16 +103,20 @@ #include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/mediastore-data-gen-tests/MediaStoreDataIncludeTests.cpp b/generated/tests/mediastore-data-gen-tests/MediaStoreDataIncludeTests.cpp index 01505e5f2d49..c7c90e8efec1 100644 --- a/generated/tests/mediastore-data-gen-tests/MediaStoreDataIncludeTests.cpp +++ b/generated/tests/mediastore-data-gen-tests/MediaStoreDataIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -21,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/mediastore-gen-tests/MediaStoreIncludeTests.cpp b/generated/tests/mediastore-gen-tests/MediaStoreIncludeTests.cpp index 1ea44f936a3a..4cab3dcea10c 100644 --- a/generated/tests/mediastore-gen-tests/MediaStoreIncludeTests.cpp +++ b/generated/tests/mediastore-gen-tests/MediaStoreIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -39,6 +43,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/mediatailor-gen-tests/MediaTailorIncludeTests.cpp b/generated/tests/mediatailor-gen-tests/MediaTailorIncludeTests.cpp index 6c0b1fd614d5..d10f9bdabdbb 100644 --- a/generated/tests/mediatailor-gen-tests/MediaTailorIncludeTests.cpp +++ b/generated/tests/mediatailor-gen-tests/MediaTailorIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -96,6 +100,7 @@ #include #include #include +#include #include #include #include @@ -112,23 +117,31 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/medical-imaging-gen-tests/MedicalImagingIncludeTests.cpp b/generated/tests/medical-imaging-gen-tests/MedicalImagingIncludeTests.cpp index 31e7c37b0a12..86fa43fac5ff 100644 --- a/generated/tests/medical-imaging-gen-tests/MedicalImagingIncludeTests.cpp +++ b/generated/tests/medical-imaging-gen-tests/MedicalImagingIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -53,10 +57,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -69,6 +76,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/memorydb-gen-tests/MemoryDBIncludeTests.cpp b/generated/tests/memorydb-gen-tests/MemoryDBIncludeTests.cpp index 961c12abddc5..57de5bf83bd2 100644 --- a/generated/tests/memorydb-gen-tests/MemoryDBIncludeTests.cpp +++ b/generated/tests/memorydb-gen-tests/MemoryDBIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -57,34 +61,47 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/meteringmarketplace-gen-tests/MarketplaceMeteringIncludeTests.cpp b/generated/tests/meteringmarketplace-gen-tests/MarketplaceMeteringIncludeTests.cpp index d62ae374bf7f..72edc5062b23 100644 --- a/generated/tests/meteringmarketplace-gen-tests/MarketplaceMeteringIncludeTests.cpp +++ b/generated/tests/meteringmarketplace-gen-tests/MarketplaceMeteringIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/mgn-gen-tests/MgnIncludeTests.cpp b/generated/tests/mgn-gen-tests/MgnIncludeTests.cpp index 8acf17a4a9a9..09aa30eeeab1 100644 --- a/generated/tests/mgn-gen-tests/MgnIncludeTests.cpp +++ b/generated/tests/mgn-gen-tests/MgnIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -79,18 +83,24 @@ #include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include @@ -168,68 +178,91 @@ #include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/migration-hub-refactor-spaces-gen-tests/MigrationHubRefactorSpacesIncludeTests.cpp b/generated/tests/migration-hub-refactor-spaces-gen-tests/MigrationHubRefactorSpacesIncludeTests.cpp index 71cc0157344d..1d769e5f9f6a 100644 --- a/generated/tests/migration-hub-refactor-spaces-gen-tests/MigrationHubRefactorSpacesIncludeTests.cpp +++ b/generated/tests/migration-hub-refactor-spaces-gen-tests/MigrationHubRefactorSpacesIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -59,14 +63,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/migrationhub-config-gen-tests/MigrationHubConfigIncludeTests.cpp b/generated/tests/migrationhub-config-gen-tests/MigrationHubConfigIncludeTests.cpp index 3e85f9bb4373..f6ad45bc6c28 100644 --- a/generated/tests/migrationhub-config-gen-tests/MigrationHubConfigIncludeTests.cpp +++ b/generated/tests/migrationhub-config-gen-tests/MigrationHubConfigIncludeTests.cpp @@ -7,16 +7,21 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/migrationhuborchestrator-gen-tests/MigrationHubOrchestratorIncludeTests.cpp b/generated/tests/migrationhuborchestrator-gen-tests/MigrationHubOrchestratorIncludeTests.cpp index a12a0fcafcd0..508abb133a5f 100644 --- a/generated/tests/migrationhuborchestrator-gen-tests/MigrationHubOrchestratorIncludeTests.cpp +++ b/generated/tests/migrationhuborchestrator-gen-tests/MigrationHubOrchestratorIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -42,20 +46,27 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/migrationhubstrategy-gen-tests/MigrationHubStrategyRecommendationsIncludeTests.cpp b/generated/tests/migrationhubstrategy-gen-tests/MigrationHubStrategyRecommendationsIncludeTests.cpp index 39dd5bfe59e3..5f7b48830912 100644 --- a/generated/tests/migrationhubstrategy-gen-tests/MigrationHubStrategyRecommendationsIncludeTests.cpp +++ b/generated/tests/migrationhubstrategy-gen-tests/MigrationHubStrategyRecommendationsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -66,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -80,14 +85,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/monitoring-gen-tests/CloudWatchIncludeTests.cpp b/generated/tests/monitoring-gen-tests/CloudWatchIncludeTests.cpp index e0432aa172af..00a2a625a607 100644 --- a/generated/tests/monitoring-gen-tests/CloudWatchIncludeTests.cpp +++ b/generated/tests/monitoring-gen-tests/CloudWatchIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -44,14 +48,18 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -77,6 +85,7 @@ #include #include #include +#include #include #include #include @@ -93,14 +102,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/mpa-gen-tests/MPAIncludeTests.cpp b/generated/tests/mpa-gen-tests/MPAIncludeTests.cpp index 372ab8f1d471..0aeaa9bab652 100644 --- a/generated/tests/mpa-gen-tests/MPAIncludeTests.cpp +++ b/generated/tests/mpa-gen-tests/MPAIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -55,18 +59,24 @@ #include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include diff --git a/generated/tests/mq-gen-tests/MQIncludeTests.cpp b/generated/tests/mq-gen-tests/MQIncludeTests.cpp index 3b8a7963aaab..be5622f698a8 100644 --- a/generated/tests/mq-gen-tests/MQIncludeTests.cpp +++ b/generated/tests/mq-gen-tests/MQIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -58,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -69,6 +74,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/mturk-requester-gen-tests/MTurkIncludeTests.cpp b/generated/tests/mturk-requester-gen-tests/MTurkIncludeTests.cpp index 69a137a75ffb..92ad2cefe1a5 100644 --- a/generated/tests/mturk-requester-gen-tests/MTurkIncludeTests.cpp +++ b/generated/tests/mturk-requester-gen-tests/MTurkIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -61,24 +65,34 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/mwaa-gen-tests/MWAAIncludeTests.cpp b/generated/tests/mwaa-gen-tests/MWAAIncludeTests.cpp index 7f8911de2fac..c6da9dea4e46 100644 --- a/generated/tests/mwaa-gen-tests/MWAAIncludeTests.cpp +++ b/generated/tests/mwaa-gen-tests/MWAAIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -30,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/mwaa-serverless-gen-tests/MWAAServerlessIncludeTests.cpp b/generated/tests/mwaa-serverless-gen-tests/MWAAServerlessIncludeTests.cpp index 83312142cdf5..7a231a1a141b 100644 --- a/generated/tests/mwaa-serverless-gen-tests/MWAAServerlessIncludeTests.cpp +++ b/generated/tests/mwaa-serverless-gen-tests/MWAAServerlessIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -30,12 +34,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/neptune-gen-tests/NeptuneIncludeTests.cpp b/generated/tests/neptune-gen-tests/NeptuneIncludeTests.cpp index 28c06375e2c4..f440a6f569dc 100644 --- a/generated/tests/neptune-gen-tests/NeptuneIncludeTests.cpp +++ b/generated/tests/neptune-gen-tests/NeptuneIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -79,42 +83,58 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/neptune-graph-gen-tests/NeptuneGraphIncludeTests.cpp b/generated/tests/neptune-graph-gen-tests/NeptuneGraphIncludeTests.cpp index c26f27093c1c..f1e9078834f8 100644 --- a/generated/tests/neptune-graph-gen-tests/NeptuneGraphIncludeTests.cpp +++ b/generated/tests/neptune-graph-gen-tests/NeptuneGraphIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -70,14 +74,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/neptunedata-gen-tests/NeptunedataIncludeTests.cpp b/generated/tests/neptunedata-gen-tests/NeptunedataIncludeTests.cpp index 499b84227a57..9722327b0f18 100644 --- a/generated/tests/neptunedata-gen-tests/NeptunedataIncludeTests.cpp +++ b/generated/tests/neptunedata-gen-tests/NeptunedataIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/network-firewall-gen-tests/NetworkFirewallIncludeTests.cpp b/generated/tests/network-firewall-gen-tests/NetworkFirewallIncludeTests.cpp index bf6234cb7234..769d0677e3f7 100644 --- a/generated/tests/network-firewall-gen-tests/NetworkFirewallIncludeTests.cpp +++ b/generated/tests/network-firewall-gen-tests/NetworkFirewallIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -147,6 +151,7 @@ #include #include #include +#include #include #include #include @@ -156,30 +161,43 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/networkflowmonitor-gen-tests/NetworkFlowMonitorIncludeTests.cpp b/generated/tests/networkflowmonitor-gen-tests/NetworkFlowMonitorIncludeTests.cpp index d2018d61ecd3..db091f591aff 100644 --- a/generated/tests/networkflowmonitor-gen-tests/NetworkFlowMonitorIncludeTests.cpp +++ b/generated/tests/networkflowmonitor-gen-tests/NetworkFlowMonitorIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -24,10 +28,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -39,8 +46,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/networkmanager-gen-tests/NetworkManagerIncludeTests.cpp b/generated/tests/networkmanager-gen-tests/NetworkManagerIncludeTests.cpp index 685871e21592..e8a64e4eb5c2 100644 --- a/generated/tests/networkmanager-gen-tests/NetworkManagerIncludeTests.cpp +++ b/generated/tests/networkmanager-gen-tests/NetworkManagerIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -128,6 +132,7 @@ #include #include #include +#include #include #include #include @@ -146,38 +151,50 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -186,12 +203,15 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -205,22 +225,30 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/networkmonitor-gen-tests/NetworkMonitorIncludeTests.cpp b/generated/tests/networkmonitor-gen-tests/NetworkMonitorIncludeTests.cpp index d460346ab8ee..8cd8396fb8db 100644 --- a/generated/tests/networkmonitor-gen-tests/NetworkMonitorIncludeTests.cpp +++ b/generated/tests/networkmonitor-gen-tests/NetworkMonitorIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -27,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/notifications-gen-tests/NotificationsIncludeTests.cpp b/generated/tests/notifications-gen-tests/NotificationsIncludeTests.cpp index 043da377b4be..c8ac38c0ce8e 100644 --- a/generated/tests/notifications-gen-tests/NotificationsIncludeTests.cpp +++ b/generated/tests/notifications-gen-tests/NotificationsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -72,26 +76,37 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/notificationscontacts-gen-tests/NotificationsContactsIncludeTests.cpp b/generated/tests/notificationscontacts-gen-tests/NotificationsContactsIncludeTests.cpp index cc45dde9dab6..bbe68066f65a 100644 --- a/generated/tests/notificationscontacts-gen-tests/NotificationsContactsIncludeTests.cpp +++ b/generated/tests/notificationscontacts-gen-tests/NotificationsContactsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -24,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/nova-act-gen-tests/NovaActIncludeTests.cpp b/generated/tests/nova-act-gen-tests/NovaActIncludeTests.cpp index 0ebcd6a34460..4a67587390ec 100644 --- a/generated/tests/nova-act-gen-tests/NovaActIncludeTests.cpp +++ b/generated/tests/nova-act-gen-tests/NovaActIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -42,14 +46,18 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/oam-gen-tests/OAMIncludeTests.cpp b/generated/tests/oam-gen-tests/OAMIncludeTests.cpp index 11cbbcd6f8b6..6c2ef0caf433 100644 --- a/generated/tests/oam-gen-tests/OAMIncludeTests.cpp +++ b/generated/tests/oam-gen-tests/OAMIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -32,12 +36,15 @@ #include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include #include diff --git a/generated/tests/observabilityadmin-gen-tests/ObservabilityAdminIncludeTests.cpp b/generated/tests/observabilityadmin-gen-tests/ObservabilityAdminIncludeTests.cpp index de164b4653f8..99ea1930316b 100644 --- a/generated/tests/observabilityadmin-gen-tests/ObservabilityAdminIncludeTests.cpp +++ b/generated/tests/observabilityadmin-gen-tests/ObservabilityAdminIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -77,20 +81,27 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/odb-gen-tests/OdbIncludeTests.cpp b/generated/tests/odb-gen-tests/OdbIncludeTests.cpp index 8dd9a7fc352f..4124fcb887d5 100644 --- a/generated/tests/odb-gen-tests/OdbIncludeTests.cpp +++ b/generated/tests/odb-gen-tests/OdbIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -184,44 +188,64 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/omics-gen-tests/OmicsIncludeTests.cpp b/generated/tests/omics-gen-tests/OmicsIncludeTests.cpp index 8887f4a797ae..679018b61ff3 100644 --- a/generated/tests/omics-gen-tests/OmicsIncludeTests.cpp +++ b/generated/tests/omics-gen-tests/OmicsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -174,60 +178,85 @@ #include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/opensearch-gen-tests/OpenSearchServiceIncludeTests.cpp b/generated/tests/opensearch-gen-tests/OpenSearchServiceIncludeTests.cpp index c154afb20f08..ea889f6b29ba 100644 --- a/generated/tests/opensearch-gen-tests/OpenSearchServiceIncludeTests.cpp +++ b/generated/tests/opensearch-gen-tests/OpenSearchServiceIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -131,6 +135,7 @@ #include #include #include +#include #include #include #include @@ -147,20 +152,25 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -220,8 +230,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -263,6 +275,7 @@ #include #include #include +#include #include #include #include @@ -271,24 +284,30 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/opensearchserverless-gen-tests/OpenSearchServerlessIncludeTests.cpp b/generated/tests/opensearchserverless-gen-tests/OpenSearchServerlessIncludeTests.cpp index 0d48e6e08ef7..d9bdf225060b 100644 --- a/generated/tests/opensearchserverless-gen-tests/OpenSearchServerlessIncludeTests.cpp +++ b/generated/tests/opensearchserverless-gen-tests/OpenSearchServerlessIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -108,20 +112,27 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/organizations-gen-tests/OrganizationsIncludeTests.cpp b/generated/tests/organizations-gen-tests/OrganizationsIncludeTests.cpp index f038dd532043..cc0e7b8eff5d 100644 --- a/generated/tests/organizations-gen-tests/OrganizationsIncludeTests.cpp +++ b/generated/tests/organizations-gen-tests/OrganizationsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -100,44 +104,62 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/osis-gen-tests/OSISIncludeTests.cpp b/generated/tests/osis-gen-tests/OSISIncludeTests.cpp index 3d9c8a9483af..b4b571762e3a 100644 --- a/generated/tests/osis-gen-tests/OSISIncludeTests.cpp +++ b/generated/tests/osis-gen-tests/OSISIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -40,10 +44,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/outposts-gen-tests/OutpostsIncludeTests.cpp b/generated/tests/outposts-gen-tests/OutpostsIncludeTests.cpp index a6d49ee125fb..da52f521b776 100644 --- a/generated/tests/outposts-gen-tests/OutpostsIncludeTests.cpp +++ b/generated/tests/outposts-gen-tests/OutpostsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -71,12 +75,15 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -94,24 +101,34 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/partnercentral-account-gen-tests/PartnerCentralAccountIncludeTests.cpp b/generated/tests/partnercentral-account-gen-tests/PartnerCentralAccountIncludeTests.cpp index ce886b1c9ec2..d6fd0559d534 100644 --- a/generated/tests/partnercentral-account-gen-tests/PartnerCentralAccountIncludeTests.cpp +++ b/generated/tests/partnercentral-account-gen-tests/PartnerCentralAccountIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -75,10 +79,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/partnercentral-benefits-gen-tests/PartnerCentralBenefitsIncludeTests.cpp b/generated/tests/partnercentral-benefits-gen-tests/PartnerCentralBenefitsIncludeTests.cpp index 25e2f8263829..5d3ab4de6630 100644 --- a/generated/tests/partnercentral-benefits-gen-tests/PartnerCentralBenefitsIncludeTests.cpp +++ b/generated/tests/partnercentral-benefits-gen-tests/PartnerCentralBenefitsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -50,10 +54,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/partnercentral-channel-gen-tests/PartnerCentralChannelIncludeTests.cpp b/generated/tests/partnercentral-channel-gen-tests/PartnerCentralChannelIncludeTests.cpp index b6e194346bb5..cdffe3fe8b64 100644 --- a/generated/tests/partnercentral-channel-gen-tests/PartnerCentralChannelIncludeTests.cpp +++ b/generated/tests/partnercentral-channel-gen-tests/PartnerCentralChannelIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -43,14 +47,17 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/partnercentral-revenue-measurement-gen-tests/PartnerCentralRevenueMeasurementIncludeTests.cpp b/generated/tests/partnercentral-revenue-measurement-gen-tests/PartnerCentralRevenueMeasurementIncludeTests.cpp index 81e856c39858..c27cb96d9ae3 100644 --- a/generated/tests/partnercentral-revenue-measurement-gen-tests/PartnerCentralRevenueMeasurementIncludeTests.cpp +++ b/generated/tests/partnercentral-revenue-measurement-gen-tests/PartnerCentralRevenueMeasurementIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -39,12 +43,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/partnercentral-selling-gen-tests/PartnerCentralSellingIncludeTests.cpp b/generated/tests/partnercentral-selling-gen-tests/PartnerCentralSellingIncludeTests.cpp index 84e93f6b7dfb..d1dbc71d0aee 100644 --- a/generated/tests/partnercentral-selling-gen-tests/PartnerCentralSellingIncludeTests.cpp +++ b/generated/tests/partnercentral-selling-gen-tests/PartnerCentralSellingIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -120,30 +124,42 @@ #include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/payment-cryptography-data-gen-tests/PaymentCryptographyDataIncludeTests.cpp b/generated/tests/payment-cryptography-data-gen-tests/PaymentCryptographyDataIncludeTests.cpp index 8c80e2c22402..f8b24b211d1b 100644 --- a/generated/tests/payment-cryptography-data-gen-tests/PaymentCryptographyDataIncludeTests.cpp +++ b/generated/tests/payment-cryptography-data-gen-tests/PaymentCryptographyDataIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/payment-cryptography-gen-tests/PaymentCryptographyIncludeTests.cpp b/generated/tests/payment-cryptography-gen-tests/PaymentCryptographyIncludeTests.cpp index cb290db61fc1..6117bfd3767f 100644 --- a/generated/tests/payment-cryptography-gen-tests/PaymentCryptographyIncludeTests.cpp +++ b/generated/tests/payment-cryptography-gen-tests/PaymentCryptographyIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -91,10 +95,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/pca-connector-ad-gen-tests/PcaConnectorAdIncludeTests.cpp b/generated/tests/pca-connector-ad-gen-tests/PcaConnectorAdIncludeTests.cpp index ee3e49426683..9840e7d9b16d 100644 --- a/generated/tests/pca-connector-ad-gen-tests/PcaConnectorAdIncludeTests.cpp +++ b/generated/tests/pca-connector-ad-gen-tests/PcaConnectorAdIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -73,16 +77,21 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/pca-connector-scep-gen-tests/PcaConnectorScepIncludeTests.cpp b/generated/tests/pca-connector-scep-gen-tests/PcaConnectorScepIncludeTests.cpp index dfc9476404d6..fb7d6db4c3e3 100644 --- a/generated/tests/pca-connector-scep-gen-tests/PcaConnectorScepIncludeTests.cpp +++ b/generated/tests/pca-connector-scep-gen-tests/PcaConnectorScepIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -35,8 +39,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/pcs-gen-tests/PCSIncludeTests.cpp b/generated/tests/pcs-gen-tests/PCSIncludeTests.cpp index 1fbff1c1e671..6d38556bbb1d 100644 --- a/generated/tests/pcs-gen-tests/PCSIncludeTests.cpp +++ b/generated/tests/pcs-gen-tests/PCSIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -55,10 +59,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/personalize-events-gen-tests/PersonalizeEventsIncludeTests.cpp b/generated/tests/personalize-events-gen-tests/PersonalizeEventsIncludeTests.cpp index 78b487c2558b..aee869c7e50b 100644 --- a/generated/tests/personalize-events-gen-tests/PersonalizeEventsIncludeTests.cpp +++ b/generated/tests/personalize-events-gen-tests/PersonalizeEventsIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/personalize-gen-tests/PersonalizeIncludeTests.cpp b/generated/tests/personalize-gen-tests/PersonalizeIncludeTests.cpp index cc6e34287087..88676edc3243 100644 --- a/generated/tests/personalize-gen-tests/PersonalizeIncludeTests.cpp +++ b/generated/tests/personalize-gen-tests/PersonalizeIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -146,38 +150,54 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/personalize-runtime-gen-tests/PersonalizeRuntimeIncludeTests.cpp b/generated/tests/personalize-runtime-gen-tests/PersonalizeRuntimeIncludeTests.cpp index a5663494e6bf..e1cfa2765433 100644 --- a/generated/tests/personalize-runtime-gen-tests/PersonalizeRuntimeIncludeTests.cpp +++ b/generated/tests/personalize-runtime-gen-tests/PersonalizeRuntimeIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/pi-gen-tests/PIIncludeTests.cpp b/generated/tests/pi-gen-tests/PIIncludeTests.cpp index e4c7b6797e12..7bbbbb3b31e3 100644 --- a/generated/tests/pi-gen-tests/PIIncludeTests.cpp +++ b/generated/tests/pi-gen-tests/PIIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -24,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -41,15 +46,20 @@ #include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/pinpoint-email-gen-tests/PinpointEmailIncludeTests.cpp b/generated/tests/pinpoint-email-gen-tests/PinpointEmailIncludeTests.cpp index e6382927402c..d2b8bdfd2f44 100644 --- a/generated/tests/pinpoint-email-gen-tests/PinpointEmailIncludeTests.cpp +++ b/generated/tests/pinpoint-email-gen-tests/PinpointEmailIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -64,6 +68,7 @@ #include #include #include +#include #include #include #include @@ -81,14 +86,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/pinpoint-gen-tests/PinpointIncludeTests.cpp b/generated/tests/pinpoint-gen-tests/PinpointIncludeTests.cpp index 397667ec1ebb..de420e92cbe8 100644 --- a/generated/tests/pinpoint-gen-tests/PinpointIncludeTests.cpp +++ b/generated/tests/pinpoint-gen-tests/PinpointIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/pinpoint-sms-voice-v2-gen-tests/PinpointSMSVoiceV2IncludeTests.cpp b/generated/tests/pinpoint-sms-voice-v2-gen-tests/PinpointSMSVoiceV2IncludeTests.cpp index 8fcb5c8bb4df..a1eb524ebc65 100644 --- a/generated/tests/pinpoint-sms-voice-v2-gen-tests/PinpointSMSVoiceV2IncludeTests.cpp +++ b/generated/tests/pinpoint-sms-voice-v2-gen-tests/PinpointSMSVoiceV2IncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -109,50 +113,73 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -177,12 +204,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/pipes-gen-tests/PipesIncludeTests.cpp b/generated/tests/pipes-gen-tests/PipesIncludeTests.cpp index bae146de91d0..85636b1e2aa4 100644 --- a/generated/tests/pipes-gen-tests/PipesIncludeTests.cpp +++ b/generated/tests/pipes-gen-tests/PipesIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -55,6 +59,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/polly-gen-tests/PollyIncludeTests.cpp b/generated/tests/polly-gen-tests/PollyIncludeTests.cpp index a49a08a85417..bfce3db70a14 100644 --- a/generated/tests/polly-gen-tests/PollyIncludeTests.cpp +++ b/generated/tests/polly-gen-tests/PollyIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -32,6 +36,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/pricing-gen-tests/PricingIncludeTests.cpp b/generated/tests/pricing-gen-tests/PricingIncludeTests.cpp index 73c4b20fc1fd..a8842f1df7c9 100644 --- a/generated/tests/pricing-gen-tests/PricingIncludeTests.cpp +++ b/generated/tests/pricing-gen-tests/PricingIncludeTests.cpp @@ -7,23 +7,31 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/pricing-plan-manager-gen-tests/PricingPlanManagerIncludeTests.cpp b/generated/tests/pricing-plan-manager-gen-tests/PricingPlanManagerIncludeTests.cpp index d20e4250222e..8beffa2bbb18 100644 --- a/generated/tests/pricing-plan-manager-gen-tests/PricingPlanManagerIncludeTests.cpp +++ b/generated/tests/pricing-plan-manager-gen-tests/PricingPlanManagerIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -29,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/proton-gen-tests/ProtonIncludeTests.cpp b/generated/tests/proton-gen-tests/ProtonIncludeTests.cpp index 59c676e0dfd7..4ca027ea8fff 100644 --- a/generated/tests/proton-gen-tests/ProtonIncludeTests.cpp +++ b/generated/tests/proton-gen-tests/ProtonIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/qapps-gen-tests/QAppsIncludeTests.cpp b/generated/tests/qapps-gen-tests/QAppsIncludeTests.cpp index 0a01ed872769..ae23fb6705fe 100644 --- a/generated/tests/qapps-gen-tests/QAppsIncludeTests.cpp +++ b/generated/tests/qapps-gen-tests/QAppsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -74,10 +78,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/qbusiness-gen-tests/QBusinessIncludeTests.cpp b/generated/tests/qbusiness-gen-tests/QBusinessIncludeTests.cpp index 0f53559e77fe..7b141fc014e1 100644 --- a/generated/tests/qbusiness-gen-tests/QBusinessIncludeTests.cpp +++ b/generated/tests/qbusiness-gen-tests/QBusinessIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -186,6 +190,7 @@ #include #include #include +#include #include #include #include @@ -233,42 +238,60 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -331,6 +354,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/qconnect-gen-tests/QConnectIncludeTests.cpp b/generated/tests/qconnect-gen-tests/QConnectIncludeTests.cpp index c167a0cdf8fe..e33f6cd197c7 100644 --- a/generated/tests/qconnect-gen-tests/QConnectIncludeTests.cpp +++ b/generated/tests/qconnect-gen-tests/QConnectIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -241,40 +245,58 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -379,13 +401,17 @@ #include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/quicksight-gen-tests/QuickSightIncludeTests.cpp b/generated/tests/quicksight-gen-tests/QuickSightIncludeTests.cpp index c06014992274..4c0f7e9e485d 100644 --- a/generated/tests/quicksight-gen-tests/QuickSightIncludeTests.cpp +++ b/generated/tests/quicksight-gen-tests/QuickSightIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -720,9 +724,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -1136,65 +1142,91 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -1205,32 +1237,42 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include @@ -1522,32 +1564,43 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/ram-gen-tests/RAMIncludeTests.cpp b/generated/tests/ram-gen-tests/RAMIncludeTests.cpp index 7856bf97be42..71bd511bb23c 100644 --- a/generated/tests/ram-gen-tests/RAMIncludeTests.cpp +++ b/generated/tests/ram-gen-tests/RAMIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -41,32 +45,46 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/rbin-gen-tests/RecycleBinIncludeTests.cpp b/generated/tests/rbin-gen-tests/RecycleBinIncludeTests.cpp index db05cecb2a2c..ba577ff96adf 100644 --- a/generated/tests/rbin-gen-tests/RecycleBinIncludeTests.cpp +++ b/generated/tests/rbin-gen-tests/RecycleBinIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -21,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/rds-data-gen-tests/RDSDataServiceIncludeTests.cpp b/generated/tests/rds-data-gen-tests/RDSDataServiceIncludeTests.cpp index 8d6fe925ab6b..ffc3f1f2506f 100644 --- a/generated/tests/rds-data-gen-tests/RDSDataServiceIncludeTests.cpp +++ b/generated/tests/rds-data-gen-tests/RDSDataServiceIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/rds-gen-tests/RDSIncludeTests.cpp b/generated/tests/rds-gen-tests/RDSIncludeTests.cpp index 7688fcc2640a..15ae0e54e7a2 100644 --- a/generated/tests/rds-gen-tests/RDSIncludeTests.cpp +++ b/generated/tests/rds-gen-tests/RDSIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -184,95 +188,136 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -282,6 +327,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/redshift-data-gen-tests/RedshiftDataAPIServiceIncludeTests.cpp b/generated/tests/redshift-data-gen-tests/RedshiftDataAPIServiceIncludeTests.cpp index 96b851d7c416..d4d3f57786b6 100644 --- a/generated/tests/redshift-data-gen-tests/RedshiftDataAPIServiceIncludeTests.cpp +++ b/generated/tests/redshift-data-gen-tests/RedshiftDataAPIServiceIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -21,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -28,18 +33,25 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/redshift-gen-tests/RedshiftIncludeTests.cpp b/generated/tests/redshift-gen-tests/RedshiftIncludeTests.cpp index 5b83506e5e96..80694b69a49c 100644 --- a/generated/tests/redshift-gen-tests/RedshiftIncludeTests.cpp +++ b/generated/tests/redshift-gen-tests/RedshiftIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -145,86 +149,121 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -254,8 +293,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -272,6 +313,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/redshift-serverless-gen-tests/RedshiftServerlessIncludeTests.cpp b/generated/tests/redshift-serverless-gen-tests/RedshiftServerlessIncludeTests.cpp index 7c5695737378..3f5564103e32 100644 --- a/generated/tests/redshift-serverless-gen-tests/RedshiftServerlessIncludeTests.cpp +++ b/generated/tests/redshift-serverless-gen-tests/RedshiftServerlessIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -89,34 +93,48 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/rekognition-gen-tests/RekognitionIncludeTests.cpp b/generated/tests/rekognition-gen-tests/RekognitionIncludeTests.cpp index a6c8ededc8c7..dd1dae2f0f2d 100644 --- a/generated/tests/rekognition-gen-tests/RekognitionIncludeTests.cpp +++ b/generated/tests/rekognition-gen-tests/RekognitionIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -96,8 +100,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -152,26 +158,34 @@ #include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -199,22 +213,30 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/repostspace-gen-tests/RepostspaceIncludeTests.cpp b/generated/tests/repostspace-gen-tests/RepostspaceIncludeTests.cpp index 68e6574416ed..bb4d987fa137 100644 --- a/generated/tests/repostspace-gen-tests/RepostspaceIncludeTests.cpp +++ b/generated/tests/repostspace-gen-tests/RepostspaceIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -40,8 +44,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/resiliencehub-gen-tests/ResilienceHubIncludeTests.cpp b/generated/tests/resiliencehub-gen-tests/ResilienceHubIncludeTests.cpp index b8a3b6e12e0a..2768d7d3c7b2 100644 --- a/generated/tests/resiliencehub-gen-tests/ResilienceHubIncludeTests.cpp +++ b/generated/tests/resiliencehub-gen-tests/ResilienceHubIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -124,46 +128,66 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/resiliencehubv2-gen-tests/Resiliencehubv2IncludeTests.cpp b/generated/tests/resiliencehubv2-gen-tests/Resiliencehubv2IncludeTests.cpp index 0995ba9ea6d4..d8050e3b429c 100644 --- a/generated/tests/resiliencehubv2-gen-tests/Resiliencehubv2IncludeTests.cpp +++ b/generated/tests/resiliencehubv2-gen-tests/Resiliencehubv2IncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -114,50 +118,71 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/resource-explorer-2-gen-tests/ResourceExplorer2IncludeTests.cpp b/generated/tests/resource-explorer-2-gen-tests/ResourceExplorer2IncludeTests.cpp index 172371df8c83..8a3f852017f0 100644 --- a/generated/tests/resource-explorer-2-gen-tests/ResourceExplorer2IncludeTests.cpp +++ b/generated/tests/resource-explorer-2-gen-tests/ResourceExplorer2IncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -41,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -54,24 +59,33 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -84,6 +98,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/resource-groups-gen-tests/ResourceGroupsIncludeTests.cpp b/generated/tests/resource-groups-gen-tests/ResourceGroupsIncludeTests.cpp index a0780035a643..84cf325d3f37 100644 --- a/generated/tests/resource-groups-gen-tests/ResourceGroupsIncludeTests.cpp +++ b/generated/tests/resource-groups-gen-tests/ResourceGroupsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -49,15 +53,19 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include @@ -72,6 +80,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/resourcegroupstaggingapi-gen-tests/ResourceGroupsTaggingAPIIncludeTests.cpp b/generated/tests/resourcegroupstaggingapi-gen-tests/ResourceGroupsTaggingAPIIncludeTests.cpp index 7f7d9edf65f2..a64bc8ab574f 100644 --- a/generated/tests/resourcegroupstaggingapi-gen-tests/ResourceGroupsTaggingAPIIncludeTests.cpp +++ b/generated/tests/resourcegroupstaggingapi-gen-tests/ResourceGroupsTaggingAPIIncludeTests.cpp @@ -7,26 +7,35 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include diff --git a/generated/tests/rolesanywhere-gen-tests/RolesAnywhereIncludeTests.cpp b/generated/tests/rolesanywhere-gen-tests/RolesAnywhereIncludeTests.cpp index d08a0c9ee61e..a7cc4e32a861 100644 --- a/generated/tests/rolesanywhere-gen-tests/RolesAnywhereIncludeTests.cpp +++ b/generated/tests/rolesanywhere-gen-tests/RolesAnywhereIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -52,14 +56,18 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/route53-gen-tests/Route53IncludeTests.cpp b/generated/tests/route53-gen-tests/Route53IncludeTests.cpp index dc6eb76d52df..2a714bf0e3b6 100644 --- a/generated/tests/route53-gen-tests/Route53IncludeTests.cpp +++ b/generated/tests/route53-gen-tests/Route53IncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -149,22 +153,28 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/route53-recovery-cluster-gen-tests/Route53RecoveryClusterIncludeTests.cpp b/generated/tests/route53-recovery-cluster-gen-tests/Route53RecoveryClusterIncludeTests.cpp index 8388288659e7..21c868725448 100644 --- a/generated/tests/route53-recovery-cluster-gen-tests/Route53RecoveryClusterIncludeTests.cpp +++ b/generated/tests/route53-recovery-cluster-gen-tests/Route53RecoveryClusterIncludeTests.cpp @@ -7,16 +7,21 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/route53-recovery-control-config-gen-tests/Route53RecoveryControlConfigIncludeTests.cpp b/generated/tests/route53-recovery-control-config-gen-tests/Route53RecoveryControlConfigIncludeTests.cpp index 9cd53fff944b..7e9b301f199b 100644 --- a/generated/tests/route53-recovery-control-config-gen-tests/Route53RecoveryControlConfigIncludeTests.cpp +++ b/generated/tests/route53-recovery-control-config-gen-tests/Route53RecoveryControlConfigIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -46,14 +50,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/route53-recovery-readiness-gen-tests/Route53RecoveryReadinessIncludeTests.cpp b/generated/tests/route53-recovery-readiness-gen-tests/Route53RecoveryReadinessIncludeTests.cpp index cf6e23998c43..b938a033efae 100644 --- a/generated/tests/route53-recovery-readiness-gen-tests/Route53RecoveryReadinessIncludeTests.cpp +++ b/generated/tests/route53-recovery-readiness-gen-tests/Route53RecoveryReadinessIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -33,33 +37,43 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include diff --git a/generated/tests/route53domains-gen-tests/Route53DomainsIncludeTests.cpp b/generated/tests/route53domains-gen-tests/Route53DomainsIncludeTests.cpp index 0dafe22036b4..ef4f1b3aa71b 100644 --- a/generated/tests/route53domains-gen-tests/Route53DomainsIncludeTests.cpp +++ b/generated/tests/route53domains-gen-tests/Route53DomainsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -62,11 +66,14 @@ #include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include @@ -108,6 +115,7 @@ #include #include #include +#include #include #include diff --git a/generated/tests/route53globalresolver-gen-tests/Route53GlobalResolverIncludeTests.cpp b/generated/tests/route53globalresolver-gen-tests/Route53GlobalResolverIncludeTests.cpp index 878038530e5e..605669a401a4 100644 --- a/generated/tests/route53globalresolver-gen-tests/Route53GlobalResolverIncludeTests.cpp +++ b/generated/tests/route53globalresolver-gen-tests/Route53GlobalResolverIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -100,24 +104,34 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/route53profiles-gen-tests/Route53ProfilesIncludeTests.cpp b/generated/tests/route53profiles-gen-tests/Route53ProfilesIncludeTests.cpp index e05d6d39ec1f..01eb13f83fe8 100644 --- a/generated/tests/route53profiles-gen-tests/Route53ProfilesIncludeTests.cpp +++ b/generated/tests/route53profiles-gen-tests/Route53ProfilesIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -33,10 +37,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/route53resolver-gen-tests/Route53ResolverIncludeTests.cpp b/generated/tests/route53resolver-gen-tests/Route53ResolverIncludeTests.cpp index 85db71c10df4..672823ed8e65 100644 --- a/generated/tests/route53resolver-gen-tests/Route53ResolverIncludeTests.cpp +++ b/generated/tests/route53resolver-gen-tests/Route53ResolverIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -133,38 +137,55 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/rtbfabric-gen-tests/RTBFabricIncludeTests.cpp b/generated/tests/rtbfabric-gen-tests/RTBFabricIncludeTests.cpp index 362cd4334dbf..0852446a4eab 100644 --- a/generated/tests/rtbfabric-gen-tests/RTBFabricIncludeTests.cpp +++ b/generated/tests/rtbfabric-gen-tests/RTBFabricIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -76,15 +80,20 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/rum-gen-tests/CloudWatchRUMIncludeTests.cpp b/generated/tests/rum-gen-tests/CloudWatchRUMIncludeTests.cpp index 9a24c45c559e..82bb4ec79f8e 100644 --- a/generated/tests/rum-gen-tests/CloudWatchRUMIncludeTests.cpp +++ b/generated/tests/rum-gen-tests/CloudWatchRUMIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -24,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -49,8 +55,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/s3-crt-gen-tests/S3CrtIncludeTests.cpp b/generated/tests/s3-crt-gen-tests/S3CrtIncludeTests.cpp index 5f42b10b8d19..892c4c32b508 100644 --- a/generated/tests/s3-crt-gen-tests/S3CrtIncludeTests.cpp +++ b/generated/tests/s3-crt-gen-tests/S3CrtIncludeTests.cpp @@ -9,17 +9,21 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -251,20 +255,25 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/s3-gen-tests/S3IncludeTests.cpp b/generated/tests/s3-gen-tests/S3IncludeTests.cpp index e99e14bb5595..1bb72fb5d016 100644 --- a/generated/tests/s3-gen-tests/S3IncludeTests.cpp +++ b/generated/tests/s3-gen-tests/S3IncludeTests.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -15,9 +16,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -249,20 +253,25 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/s3control-gen-tests/S3ControlIncludeTests.cpp b/generated/tests/s3control-gen-tests/S3ControlIncludeTests.cpp index 0c85f1e6e5a6..5eb209f9d276 100644 --- a/generated/tests/s3control-gen-tests/S3ControlIncludeTests.cpp +++ b/generated/tests/s3control-gen-tests/S3ControlIncludeTests.cpp @@ -8,12 +8,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -187,32 +191,44 @@ #include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include #include diff --git a/generated/tests/s3files-gen-tests/S3FilesIncludeTests.cpp b/generated/tests/s3files-gen-tests/S3FilesIncludeTests.cpp index 729a6d273189..1f840040b727 100644 --- a/generated/tests/s3files-gen-tests/S3FilesIncludeTests.cpp +++ b/generated/tests/s3files-gen-tests/S3FilesIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -42,14 +46,18 @@ #include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/s3outposts-gen-tests/S3OutpostsIncludeTests.cpp b/generated/tests/s3outposts-gen-tests/S3OutpostsIncludeTests.cpp index 140c2450e6e4..096cd51376e6 100644 --- a/generated/tests/s3outposts-gen-tests/S3OutpostsIncludeTests.cpp +++ b/generated/tests/s3outposts-gen-tests/S3OutpostsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -20,10 +24,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/s3tables-gen-tests/S3TablesIncludeTests.cpp b/generated/tests/s3tables-gen-tests/S3TablesIncludeTests.cpp index 69ca8884dffb..34ed2eb4db7f 100644 --- a/generated/tests/s3tables-gen-tests/S3TablesIncludeTests.cpp +++ b/generated/tests/s3tables-gen-tests/S3TablesIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -82,10 +86,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/s3vectors-gen-tests/S3VectorsIncludeTests.cpp b/generated/tests/s3vectors-gen-tests/S3VectorsIncludeTests.cpp index abb66dcefbaa..03e61459b375 100644 --- a/generated/tests/s3vectors-gen-tests/S3VectorsIncludeTests.cpp +++ b/generated/tests/s3vectors-gen-tests/S3VectorsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -39,13 +43,16 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include +#include #include #include #include @@ -55,6 +62,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/sagemaker-a2i-runtime-gen-tests/AugmentedAIRuntimeIncludeTests.cpp b/generated/tests/sagemaker-a2i-runtime-gen-tests/AugmentedAIRuntimeIncludeTests.cpp index 3d07c6bf4622..282f3b454449 100644 --- a/generated/tests/sagemaker-a2i-runtime-gen-tests/AugmentedAIRuntimeIncludeTests.cpp +++ b/generated/tests/sagemaker-a2i-runtime-gen-tests/AugmentedAIRuntimeIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -23,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/sagemaker-edge-gen-tests/SagemakerEdgeManagerIncludeTests.cpp b/generated/tests/sagemaker-edge-gen-tests/SagemakerEdgeManagerIncludeTests.cpp index a1200d583a74..9ea33567c8a2 100644 --- a/generated/tests/sagemaker-edge-gen-tests/SagemakerEdgeManagerIncludeTests.cpp +++ b/generated/tests/sagemaker-edge-gen-tests/SagemakerEdgeManagerIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/sagemaker-featurestore-runtime-gen-tests/SageMakerFeatureStoreRuntimeIncludeTests.cpp b/generated/tests/sagemaker-featurestore-runtime-gen-tests/SageMakerFeatureStoreRuntimeIncludeTests.cpp index 9dff458da4bc..872e74dda0ca 100644 --- a/generated/tests/sagemaker-featurestore-runtime-gen-tests/SageMakerFeatureStoreRuntimeIncludeTests.cpp +++ b/generated/tests/sagemaker-featurestore-runtime-gen-tests/SageMakerFeatureStoreRuntimeIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -28,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/sagemaker-gen-tests/SageMakerIncludeTests.cpp b/generated/tests/sagemaker-gen-tests/SageMakerIncludeTests.cpp index b0383c36578e..a46fa05e2787 100644 --- a/generated/tests/sagemaker-gen-tests/SageMakerIncludeTests.cpp +++ b/generated/tests/sagemaker-gen-tests/SageMakerIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -388,6 +392,7 @@ #include #include #include +#include #include #include #include @@ -735,6 +740,7 @@ #include #include #include +#include #include #include #include @@ -1041,73 +1047,104 @@ #include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -1116,120 +1153,176 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include @@ -1510,6 +1603,7 @@ #include #include #include +#include #include #include #include @@ -1599,6 +1693,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/sagemaker-geospatial-gen-tests/SageMakerGeospatialIncludeTests.cpp b/generated/tests/sagemaker-geospatial-gen-tests/SageMakerGeospatialIncludeTests.cpp index e42c193d8e92..01ea977976cb 100644 --- a/generated/tests/sagemaker-geospatial-gen-tests/SageMakerGeospatialIncludeTests.cpp +++ b/generated/tests/sagemaker-geospatial-gen-tests/SageMakerGeospatialIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -64,13 +68,16 @@ #include #include #include +#include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -96,6 +103,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/sagemaker-metrics-gen-tests/SageMakerMetricsIncludeTests.cpp b/generated/tests/sagemaker-metrics-gen-tests/SageMakerMetricsIncludeTests.cpp index a6c0b6fc334c..64da9645a746 100644 --- a/generated/tests/sagemaker-metrics-gen-tests/SageMakerMetricsIncludeTests.cpp +++ b/generated/tests/sagemaker-metrics-gen-tests/SageMakerMetricsIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/sagemaker-runtime-gen-tests/SageMakerRuntimeIncludeTests.cpp b/generated/tests/sagemaker-runtime-gen-tests/SageMakerRuntimeIncludeTests.cpp index 21972d5f3683..6440f946fbc9 100644 --- a/generated/tests/sagemaker-runtime-gen-tests/SageMakerRuntimeIncludeTests.cpp +++ b/generated/tests/sagemaker-runtime-gen-tests/SageMakerRuntimeIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/sagemaker-runtime-http2-gen-tests/SageMakerRuntimeHTTP2IncludeTests.cpp b/generated/tests/sagemaker-runtime-http2-gen-tests/SageMakerRuntimeHTTP2IncludeTests.cpp index 358c9598ad20..2917b4c30b5b 100644 --- a/generated/tests/sagemaker-runtime-http2-gen-tests/SageMakerRuntimeHTTP2IncludeTests.cpp +++ b/generated/tests/sagemaker-runtime-http2-gen-tests/SageMakerRuntimeHTTP2IncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/sagemakerjobruntime-gen-tests/SagemakerJobRuntimeIncludeTests.cpp b/generated/tests/sagemakerjobruntime-gen-tests/SagemakerJobRuntimeIncludeTests.cpp index b94e0fd702e6..8a8561a9c8df 100644 --- a/generated/tests/sagemakerjobruntime-gen-tests/SagemakerJobRuntimeIncludeTests.cpp +++ b/generated/tests/sagemakerjobruntime-gen-tests/SagemakerJobRuntimeIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/savingsplans-gen-tests/SavingsPlansIncludeTests.cpp b/generated/tests/savingsplans-gen-tests/SavingsPlansIncludeTests.cpp index d4760069b5c7..7700f6b2a436 100644 --- a/generated/tests/savingsplans-gen-tests/SavingsPlansIncludeTests.cpp +++ b/generated/tests/savingsplans-gen-tests/SavingsPlansIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/scheduler-gen-tests/SchedulerIncludeTests.cpp b/generated/tests/scheduler-gen-tests/SchedulerIncludeTests.cpp index 72c5443eddf4..f5211cdaac75 100644 --- a/generated/tests/scheduler-gen-tests/SchedulerIncludeTests.cpp +++ b/generated/tests/scheduler-gen-tests/SchedulerIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -36,8 +40,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/schemas-gen-tests/SchemasIncludeTests.cpp b/generated/tests/schemas-gen-tests/SchemasIncludeTests.cpp index 3ab8cf9fe9d5..65a17faf082e 100644 --- a/generated/tests/schemas-gen-tests/SchemasIncludeTests.cpp +++ b/generated/tests/schemas-gen-tests/SchemasIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -48,12 +52,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -69,6 +77,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/sdb-gen-tests/SimpleDBIncludeTests.cpp b/generated/tests/sdb-gen-tests/SimpleDBIncludeTests.cpp index 59cdcbe401c8..4a0f81131d80 100644 --- a/generated/tests/sdb-gen-tests/SimpleDBIncludeTests.cpp +++ b/generated/tests/sdb-gen-tests/SimpleDBIncludeTests.cpp @@ -10,8 +10,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/secretsmanager-gen-tests/SecretsManagerIncludeTests.cpp b/generated/tests/secretsmanager-gen-tests/SecretsManagerIncludeTests.cpp index ff24dfa57ad0..34bd1ade3336 100644 --- a/generated/tests/secretsmanager-gen-tests/SecretsManagerIncludeTests.cpp +++ b/generated/tests/secretsmanager-gen-tests/SecretsManagerIncludeTests.cpp @@ -7,13 +7,18 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include +#include #include #include #include @@ -35,8 +40,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/security-ir-gen-tests/SecurityIRIncludeTests.cpp b/generated/tests/security-ir-gen-tests/SecurityIRIncludeTests.cpp index 75823d88f36a..6ffdd5b3591d 100644 --- a/generated/tests/security-ir-gen-tests/SecurityIRIncludeTests.cpp +++ b/generated/tests/security-ir-gen-tests/SecurityIRIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -53,17 +57,22 @@ #include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include diff --git a/generated/tests/securityagent-gen-tests/SecurityAgentIncludeTests.cpp b/generated/tests/securityagent-gen-tests/SecurityAgentIncludeTests.cpp index e4136e3afc27..03e751b512ba 100644 --- a/generated/tests/securityagent-gen-tests/SecurityAgentIncludeTests.cpp +++ b/generated/tests/securityagent-gen-tests/SecurityAgentIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -189,51 +193,73 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/securityhub-gen-tests/SecurityHubIncludeTests.cpp b/generated/tests/securityhub-gen-tests/SecurityHubIncludeTests.cpp index 8cf4cfe4ba34..189a98df2415 100644 --- a/generated/tests/securityhub-gen-tests/SecurityHubIncludeTests.cpp +++ b/generated/tests/securityhub-gen-tests/SecurityHubIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -675,20 +679,25 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include @@ -764,34 +773,43 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include @@ -829,34 +847,45 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/securitylake-gen-tests/SecurityLakeIncludeTests.cpp b/generated/tests/securitylake-gen-tests/SecurityLakeIncludeTests.cpp index 3bf95f0fb976..2a8a3dd4d770 100644 --- a/generated/tests/securitylake-gen-tests/SecurityLakeIncludeTests.cpp +++ b/generated/tests/securitylake-gen-tests/SecurityLakeIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -73,18 +77,22 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/serverlessrepo-gen-tests/ServerlessApplicationRepositoryIncludeTests.cpp b/generated/tests/serverlessrepo-gen-tests/ServerlessApplicationRepositoryIncludeTests.cpp index 5cb594d61084..60e34226b322 100644 --- a/generated/tests/serverlessrepo-gen-tests/ServerlessApplicationRepositoryIncludeTests.cpp +++ b/generated/tests/serverlessrepo-gen-tests/ServerlessApplicationRepositoryIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -36,10 +40,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/service-quotas-gen-tests/ServiceQuotasIncludeTests.cpp b/generated/tests/service-quotas-gen-tests/ServiceQuotasIncludeTests.cpp index 9c7c24a91c91..30efa0bc1f46 100644 --- a/generated/tests/service-quotas-gen-tests/ServiceQuotasIncludeTests.cpp +++ b/generated/tests/service-quotas-gen-tests/ServiceQuotasIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -38,16 +42,22 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/servicecatalog-appregistry-gen-tests/AppRegistryIncludeTests.cpp b/generated/tests/servicecatalog-appregistry-gen-tests/AppRegistryIncludeTests.cpp index dc5fa642daaf..e4f458dc3abf 100644 --- a/generated/tests/servicecatalog-appregistry-gen-tests/AppRegistryIncludeTests.cpp +++ b/generated/tests/servicecatalog-appregistry-gen-tests/AppRegistryIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -47,14 +51,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/servicecatalog-gen-tests/ServiceCatalogIncludeTests.cpp b/generated/tests/servicecatalog-gen-tests/ServiceCatalogIncludeTests.cpp index c8f7e716894d..c3fb8e849004 100644 --- a/generated/tests/servicecatalog-gen-tests/ServiceCatalogIncludeTests.cpp +++ b/generated/tests/servicecatalog-gen-tests/ServiceCatalogIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -83,6 +87,7 @@ #include #include #include +#include #include #include #include @@ -132,6 +137,7 @@ #include #include #include +#include #include #include #include @@ -140,26 +146,36 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -167,15 +183,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -239,10 +259,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/servicediscovery-gen-tests/ServiceDiscoveryIncludeTests.cpp b/generated/tests/servicediscovery-gen-tests/ServiceDiscoveryIncludeTests.cpp index d96fa60d7464..1556e7c327e4 100644 --- a/generated/tests/servicediscovery-gen-tests/ServiceDiscoveryIncludeTests.cpp +++ b/generated/tests/servicediscovery-gen-tests/ServiceDiscoveryIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -42,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -62,12 +67,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/sesv2-gen-tests/SESV2IncludeTests.cpp b/generated/tests/sesv2-gen-tests/SESV2IncludeTests.cpp index 076857097e6e..f71dfed9b1f1 100644 --- a/generated/tests/sesv2-gen-tests/SESV2IncludeTests.cpp +++ b/generated/tests/sesv2-gen-tests/SESV2IncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -159,6 +163,7 @@ #include #include #include +#include #include #include #include @@ -205,46 +210,64 @@ #include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/shield-gen-tests/ShieldIncludeTests.cpp b/generated/tests/shield-gen-tests/ShieldIncludeTests.cpp index 8a498b999f8d..76b9654c6704 100644 --- a/generated/tests/shield-gen-tests/ShieldIncludeTests.cpp +++ b/generated/tests/shield-gen-tests/ShieldIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -82,12 +86,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/signer-data-gen-tests/SignerDataIncludeTests.cpp b/generated/tests/signer-data-gen-tests/SignerDataIncludeTests.cpp index 451ff9321304..03d115ca9c67 100644 --- a/generated/tests/signer-data-gen-tests/SignerDataIncludeTests.cpp +++ b/generated/tests/signer-data-gen-tests/SignerDataIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/signer-gen-tests/SignerIncludeTests.cpp b/generated/tests/signer-gen-tests/SignerIncludeTests.cpp index 13aebbde25bf..566b50e3875a 100644 --- a/generated/tests/signer-gen-tests/SignerIncludeTests.cpp +++ b/generated/tests/signer-gen-tests/SignerIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -37,10 +41,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/signin-gen-tests/SigninIncludeTests.cpp b/generated/tests/signin-gen-tests/SigninIncludeTests.cpp index a6456baa72af..94b6eba08a27 100644 --- a/generated/tests/signin-gen-tests/SigninIncludeTests.cpp +++ b/generated/tests/signin-gen-tests/SigninIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -33,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/simpledbv2-gen-tests/SimpleDBv2IncludeTests.cpp b/generated/tests/simpledbv2-gen-tests/SimpleDBv2IncludeTests.cpp index 9e0a32a1b8ab..dc7a1c0fe9bb 100644 --- a/generated/tests/simpledbv2-gen-tests/SimpleDBv2IncludeTests.cpp +++ b/generated/tests/simpledbv2-gen-tests/SimpleDBv2IncludeTests.cpp @@ -7,16 +7,21 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/sms-voice-gen-tests/PinpointSMSVoiceIncludeTests.cpp b/generated/tests/sms-voice-gen-tests/PinpointSMSVoiceIncludeTests.cpp index e2cf0712e6c0..797256959df3 100644 --- a/generated/tests/sms-voice-gen-tests/PinpointSMSVoiceIncludeTests.cpp +++ b/generated/tests/sms-voice-gen-tests/PinpointSMSVoiceIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/snow-device-management-gen-tests/SnowDeviceManagementIncludeTests.cpp b/generated/tests/snow-device-management-gen-tests/SnowDeviceManagementIncludeTests.cpp index 4171a8c62fc2..dd98602a54cb 100644 --- a/generated/tests/snow-device-management-gen-tests/SnowDeviceManagementIncludeTests.cpp +++ b/generated/tests/snow-device-management-gen-tests/SnowDeviceManagementIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -39,14 +43,18 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/snowball-gen-tests/SnowballIncludeTests.cpp b/generated/tests/snowball-gen-tests/SnowballIncludeTests.cpp index 3f79e2ece0da..a0e09275c742 100644 --- a/generated/tests/snowball-gen-tests/SnowballIncludeTests.cpp +++ b/generated/tests/snowball-gen-tests/SnowballIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -38,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -70,16 +75,22 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/sns-gen-tests/SNSIncludeTests.cpp b/generated/tests/sns-gen-tests/SNSIncludeTests.cpp index 4bc7ae64a3e6..ae9913562e7e 100644 --- a/generated/tests/sns-gen-tests/SNSIncludeTests.cpp +++ b/generated/tests/sns-gen-tests/SNSIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -47,22 +51,30 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/socialmessaging-gen-tests/SocialMessagingIncludeTests.cpp b/generated/tests/socialmessaging-gen-tests/SocialMessagingIncludeTests.cpp index fe71e05aa42a..4cef25fa8fd0 100644 --- a/generated/tests/socialmessaging-gen-tests/SocialMessagingIncludeTests.cpp +++ b/generated/tests/socialmessaging-gen-tests/SocialMessagingIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -53,16 +57,21 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/sqs-gen-tests/SQSIncludeTests.cpp b/generated/tests/sqs-gen-tests/SQSIncludeTests.cpp index e40a2310f126..abc0985850d8 100644 --- a/generated/tests/sqs-gen-tests/SQSIncludeTests.cpp +++ b/generated/tests/sqs-gen-tests/SQSIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -34,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +46,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/ssm-contacts-gen-tests/SSMContactsIncludeTests.cpp b/generated/tests/ssm-contacts-gen-tests/SSMContactsIncludeTests.cpp index 51b0722f2d5c..f941bf089514 100644 --- a/generated/tests/ssm-contacts-gen-tests/SSMContactsIncludeTests.cpp +++ b/generated/tests/ssm-contacts-gen-tests/SSMContactsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -66,26 +70,37 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/ssm-gen-tests/SSMIncludeTests.cpp b/generated/tests/ssm-gen-tests/SSMIncludeTests.cpp index a43ebc8c4418..ed8dee1521e2 100644 --- a/generated/tests/ssm-gen-tests/SSMIncludeTests.cpp +++ b/generated/tests/ssm-gen-tests/SSMIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -146,70 +150,99 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -265,8 +298,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -283,12 +318,15 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -297,6 +335,7 @@ #include #include #include +#include #include #include #include @@ -342,40 +381,56 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -603,6 +658,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/ssm-guiconnect-gen-tests/SSMGuiConnectIncludeTests.cpp b/generated/tests/ssm-guiconnect-gen-tests/SSMGuiConnectIncludeTests.cpp index 75ff409d4b95..71fbd21d54ad 100644 --- a/generated/tests/ssm-guiconnect-gen-tests/SSMGuiConnectIncludeTests.cpp +++ b/generated/tests/ssm-guiconnect-gen-tests/SSMGuiConnectIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/ssm-incidents-gen-tests/SSMIncidentsIncludeTests.cpp b/generated/tests/ssm-incidents-gen-tests/SSMIncidentsIncludeTests.cpp index 4b389ceac40a..0f3e437c7106 100644 --- a/generated/tests/ssm-incidents-gen-tests/SSMIncidentsIncludeTests.cpp +++ b/generated/tests/ssm-incidents-gen-tests/SSMIncidentsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -54,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -69,18 +74,24 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/ssm-quicksetup-gen-tests/SSMQuickSetupIncludeTests.cpp b/generated/tests/ssm-quicksetup-gen-tests/SSMQuickSetupIncludeTests.cpp index f78bae887c59..3d1f1aafae41 100644 --- a/generated/tests/ssm-quicksetup-gen-tests/SSMQuickSetupIncludeTests.cpp +++ b/generated/tests/ssm-quicksetup-gen-tests/SSMQuickSetupIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -28,8 +32,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/ssm-sap-gen-tests/SsmSapIncludeTests.cpp b/generated/tests/ssm-sap-gen-tests/SsmSapIncludeTests.cpp index 683a32e80227..f222b5a2b076 100644 --- a/generated/tests/ssm-sap-gen-tests/SsmSapIncludeTests.cpp +++ b/generated/tests/ssm-sap-gen-tests/SsmSapIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -62,22 +66,31 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/sso-admin-gen-tests/SSOAdminIncludeTests.cpp b/generated/tests/sso-admin-gen-tests/SSOAdminIncludeTests.cpp index 8c94a0b6ae3f..dd45892b8447 100644 --- a/generated/tests/sso-admin-gen-tests/SSOAdminIncludeTests.cpp +++ b/generated/tests/sso-admin-gen-tests/SSOAdminIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -131,49 +135,70 @@ #include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/sso-gen-tests/SSOIncludeTests.cpp b/generated/tests/sso-gen-tests/SSOIncludeTests.cpp index 16342e5c2860..c0fd9ad06cad 100644 --- a/generated/tests/sso-gen-tests/SSOIncludeTests.cpp +++ b/generated/tests/sso-gen-tests/SSOIncludeTests.cpp @@ -7,17 +7,23 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/sso-oidc-gen-tests/SSOOIDCIncludeTests.cpp b/generated/tests/sso-oidc-gen-tests/SSOOIDCIncludeTests.cpp index 8324b9777ac9..1bb8234ddc7c 100644 --- a/generated/tests/sso-oidc-gen-tests/SSOOIDCIncludeTests.cpp +++ b/generated/tests/sso-oidc-gen-tests/SSOOIDCIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/states-gen-tests/SFNIncludeTests.cpp b/generated/tests/states-gen-tests/SFNIncludeTests.cpp index be35449554f9..82c30790588c 100644 --- a/generated/tests/states-gen-tests/SFNIncludeTests.cpp +++ b/generated/tests/states-gen-tests/SFNIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -65,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -84,16 +89,20 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/storagegateway-gen-tests/StorageGatewayIncludeTests.cpp b/generated/tests/storagegateway-gen-tests/StorageGatewayIncludeTests.cpp index 49518bcbad45..f081ade84ac6 100644 --- a/generated/tests/storagegateway-gen-tests/StorageGatewayIncludeTests.cpp +++ b/generated/tests/storagegateway-gen-tests/StorageGatewayIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -119,14 +123,18 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -158,26 +166,34 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/sts-gen-tests/STSIncludeTests.cpp b/generated/tests/sts-gen-tests/STSIncludeTests.cpp index 39d6e4a9a7f0..58122bdd7bf6 100644 --- a/generated/tests/sts-gen-tests/STSIncludeTests.cpp +++ b/generated/tests/sts-gen-tests/STSIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/supplychain-gen-tests/SupplyChainIncludeTests.cpp b/generated/tests/supplychain-gen-tests/SupplyChainIncludeTests.cpp index c49894629e9f..3c856b1e9e89 100644 --- a/generated/tests/supplychain-gen-tests/SupplyChainIncludeTests.cpp +++ b/generated/tests/supplychain-gen-tests/SupplyChainIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -93,16 +97,22 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/support-app-gen-tests/SupportAppIncludeTests.cpp b/generated/tests/support-app-gen-tests/SupportAppIncludeTests.cpp index dc80b5337a1e..d2ad6c4226f4 100644 --- a/generated/tests/support-app-gen-tests/SupportAppIncludeTests.cpp +++ b/generated/tests/support-app-gen-tests/SupportAppIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -24,8 +28,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/support-gen-tests/SupportIncludeTests.cpp b/generated/tests/support-gen-tests/SupportIncludeTests.cpp index b5fe9e580756..0adb2e43c80b 100644 --- a/generated/tests/support-gen-tests/SupportIncludeTests.cpp +++ b/generated/tests/support-gen-tests/SupportIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -28,8 +32,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/supportauthz-gen-tests/SupportAuthZIncludeTests.cpp b/generated/tests/supportauthz-gen-tests/SupportAuthZIncludeTests.cpp index 148e5ebde40b..29856447092c 100644 --- a/generated/tests/supportauthz-gen-tests/SupportAuthZIncludeTests.cpp +++ b/generated/tests/supportauthz-gen-tests/SupportAuthZIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -26,10 +30,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/sustainability-gen-tests/SustainabilityIncludeTests.cpp b/generated/tests/sustainability-gen-tests/SustainabilityIncludeTests.cpp index 8a52e9af8183..4896820b00b6 100644 --- a/generated/tests/sustainability-gen-tests/SustainabilityIncludeTests.cpp +++ b/generated/tests/sustainability-gen-tests/SustainabilityIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -21,12 +25,16 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/swf-gen-tests/SWFIncludeTests.cpp b/generated/tests/swf-gen-tests/SWFIncludeTests.cpp index 2581cc4d0539..ab9b56c973e8 100644 --- a/generated/tests/swf-gen-tests/SWFIncludeTests.cpp +++ b/generated/tests/swf-gen-tests/SWFIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -83,6 +87,7 @@ #include #include #include +#include #include #include #include @@ -92,21 +97,27 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/synthetics-gen-tests/SyntheticsIncludeTests.cpp b/generated/tests/synthetics-gen-tests/SyntheticsIncludeTests.cpp index 26813c560360..9490bab4a6e1 100644 --- a/generated/tests/synthetics-gen-tests/SyntheticsIncludeTests.cpp +++ b/generated/tests/synthetics-gen-tests/SyntheticsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -50,10 +54,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -63,16 +70,20 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/taxsettings-gen-tests/TaxSettingsIncludeTests.cpp b/generated/tests/taxsettings-gen-tests/TaxSettingsIncludeTests.cpp index 63a9a7ff0333..a168cca774b0 100644 --- a/generated/tests/taxsettings-gen-tests/TaxSettingsIncludeTests.cpp +++ b/generated/tests/taxsettings-gen-tests/TaxSettingsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -67,10 +71,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/textract-gen-tests/TextractIncludeTests.cpp b/generated/tests/textract-gen-tests/TextractIncludeTests.cpp index c5e8ea4808e5..9bee08e51941 100644 --- a/generated/tests/textract-gen-tests/TextractIncludeTests.cpp +++ b/generated/tests/textract-gen-tests/TextractIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -86,8 +90,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/timestream-influxdb-gen-tests/TimestreamInfluxDBIncludeTests.cpp b/generated/tests/timestream-influxdb-gen-tests/TimestreamInfluxDBIncludeTests.cpp index 106f11689cf9..e7e470957dec 100644 --- a/generated/tests/timestream-influxdb-gen-tests/TimestreamInfluxDBIncludeTests.cpp +++ b/generated/tests/timestream-influxdb-gen-tests/TimestreamInfluxDBIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -61,14 +65,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/timestream-query-gen-tests/TimestreamQueryIncludeTests.cpp b/generated/tests/timestream-query-gen-tests/TimestreamQueryIncludeTests.cpp index ef897a1e06a6..193accf65469 100644 --- a/generated/tests/timestream-query-gen-tests/TimestreamQueryIncludeTests.cpp +++ b/generated/tests/timestream-query-gen-tests/TimestreamQueryIncludeTests.cpp @@ -8,12 +8,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -38,8 +42,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -57,6 +63,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/timestream-write-gen-tests/TimestreamWriteIncludeTests.cpp b/generated/tests/timestream-write-gen-tests/TimestreamWriteIncludeTests.cpp index 22cbfff93120..c1e212ea91be 100644 --- a/generated/tests/timestream-write-gen-tests/TimestreamWriteIncludeTests.cpp +++ b/generated/tests/timestream-write-gen-tests/TimestreamWriteIncludeTests.cpp @@ -8,12 +8,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -46,10 +50,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/tnb-gen-tests/TnbIncludeTests.cpp b/generated/tests/tnb-gen-tests/TnbIncludeTests.cpp index 5889310acd97..90e2736dab78 100644 --- a/generated/tests/tnb-gen-tests/TnbIncludeTests.cpp +++ b/generated/tests/tnb-gen-tests/TnbIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -61,22 +65,27 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/transcribe-gen-tests/TranscribeServiceIncludeTests.cpp b/generated/tests/transcribe-gen-tests/TranscribeServiceIncludeTests.cpp index edbfd4d55651..712b3bfdbc2a 100644 --- a/generated/tests/transcribe-gen-tests/TranscribeServiceIncludeTests.cpp +++ b/generated/tests/transcribe-gen-tests/TranscribeServiceIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -75,24 +79,33 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/transcribestreaming-gen-tests/TranscribeStreamingServiceIncludeTests.cpp b/generated/tests/transcribestreaming-gen-tests/TranscribeStreamingServiceIncludeTests.cpp index b9739fdb31b6..0bd5900c5457 100644 --- a/generated/tests/transcribestreaming-gen-tests/TranscribeStreamingServiceIncludeTests.cpp +++ b/generated/tests/transcribestreaming-gen-tests/TranscribeStreamingServiceIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/translate-gen-tests/TranslateIncludeTests.cpp b/generated/tests/translate-gen-tests/TranslateIncludeTests.cpp index d31bc16de82d..c35c18784f6e 100644 --- a/generated/tests/translate-gen-tests/TranslateIncludeTests.cpp +++ b/generated/tests/translate-gen-tests/TranslateIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -39,14 +43,18 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/trustedadvisor-gen-tests/TrustedAdvisorIncludeTests.cpp b/generated/tests/trustedadvisor-gen-tests/TrustedAdvisorIncludeTests.cpp index 4cd9d37ec65c..19f4aa7bd1c4 100644 --- a/generated/tests/trustedadvisor-gen-tests/TrustedAdvisorIncludeTests.cpp +++ b/generated/tests/trustedadvisor-gen-tests/TrustedAdvisorIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -22,18 +26,25 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/uxc-gen-tests/UxcIncludeTests.cpp b/generated/tests/uxc-gen-tests/UxcIncludeTests.cpp index 6426b9977e1f..74165495cee0 100644 --- a/generated/tests/uxc-gen-tests/UxcIncludeTests.cpp +++ b/generated/tests/uxc-gen-tests/UxcIncludeTests.cpp @@ -7,15 +7,20 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include +#include #include #include #include diff --git a/generated/tests/verifiedpermissions-gen-tests/VerifiedPermissionsIncludeTests.cpp b/generated/tests/verifiedpermissions-gen-tests/VerifiedPermissionsIncludeTests.cpp index ea5b1b215654..84a83ccc7164 100644 --- a/generated/tests/verifiedpermissions-gen-tests/VerifiedPermissionsIncludeTests.cpp +++ b/generated/tests/verifiedpermissions-gen-tests/VerifiedPermissionsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -94,14 +98,19 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/voice-id-gen-tests/VoiceIDIncludeTests.cpp b/generated/tests/voice-id-gen-tests/VoiceIDIncludeTests.cpp index a3b59602db08..9191284af19f 100644 --- a/generated/tests/voice-id-gen-tests/VoiceIDIncludeTests.cpp +++ b/generated/tests/voice-id-gen-tests/VoiceIDIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -66,18 +70,24 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/vpc-lattice-gen-tests/VPCLatticeIncludeTests.cpp b/generated/tests/vpc-lattice-gen-tests/VPCLatticeIncludeTests.cpp index 92a9487dd318..f781ccbfa563 100644 --- a/generated/tests/vpc-lattice-gen-tests/VPCLatticeIncludeTests.cpp +++ b/generated/tests/vpc-lattice-gen-tests/VPCLatticeIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -117,36 +121,51 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/waf-gen-tests/WAFIncludeTests.cpp b/generated/tests/waf-gen-tests/WAFIncludeTests.cpp index 674591e5713e..297c2cefc481 100644 --- a/generated/tests/waf-gen-tests/WAFIncludeTests.cpp +++ b/generated/tests/waf-gen-tests/WAFIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/waf-regional-gen-tests/WAFRegionalIncludeTests.cpp b/generated/tests/waf-regional-gen-tests/WAFRegionalIncludeTests.cpp index 06e14916da67..57b8f1768536 100644 --- a/generated/tests/waf-regional-gen-tests/WAFRegionalIncludeTests.cpp +++ b/generated/tests/waf-regional-gen-tests/WAFRegionalIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/wafv2-gen-tests/WAFV2IncludeTests.cpp b/generated/tests/wafv2-gen-tests/WAFV2IncludeTests.cpp index 679aed4ddbed..5c01d81aca05 100644 --- a/generated/tests/wafv2-gen-tests/WAFV2IncludeTests.cpp +++ b/generated/tests/wafv2-gen-tests/WAFV2IncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/wellarchitected-gen-tests/WellArchitectedIncludeTests.cpp b/generated/tests/wellarchitected-gen-tests/WellArchitectedIncludeTests.cpp index 5a562cd8323e..a352d25a75b0 100644 --- a/generated/tests/wellarchitected-gen-tests/WellArchitectedIncludeTests.cpp +++ b/generated/tests/wellarchitected-gen-tests/WellArchitectedIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -113,6 +117,7 @@ #include #include #include +#include #include #include #include @@ -163,54 +168,78 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/wickr-gen-tests/WickrIncludeTests.cpp b/generated/tests/wickr-gen-tests/WickrIncludeTests.cpp index d40d20d67549..67a1ba23cbf9 100644 --- a/generated/tests/wickr-gen-tests/WickrIncludeTests.cpp +++ b/generated/tests/wickr-gen-tests/WickrIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -82,20 +86,28 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/wisdom-gen-tests/ConnectWisdomServiceIncludeTests.cpp b/generated/tests/wisdom-gen-tests/ConnectWisdomServiceIncludeTests.cpp index 9ac110b920cb..e99a659c8292 100644 --- a/generated/tests/wisdom-gen-tests/ConnectWisdomServiceIncludeTests.cpp +++ b/generated/tests/wisdom-gen-tests/ConnectWisdomServiceIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -88,16 +92,22 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -133,11 +143,14 @@ #include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/workdocs-gen-tests/WorkDocsIncludeTests.cpp b/generated/tests/workdocs-gen-tests/WorkDocsIncludeTests.cpp index 7641c938046c..988e50621f7d 100644 --- a/generated/tests/workdocs-gen-tests/WorkDocsIncludeTests.cpp +++ b/generated/tests/workdocs-gen-tests/WorkDocsIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -52,22 +56,31 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include @@ -126,6 +139,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/workmail-gen-tests/WorkMailIncludeTests.cpp b/generated/tests/workmail-gen-tests/WorkMailIncludeTests.cpp index c00bcb8ebecb..4e48342cdf1a 100644 --- a/generated/tests/workmail-gen-tests/WorkMailIncludeTests.cpp +++ b/generated/tests/workmail-gen-tests/WorkMailIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -141,42 +145,57 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/workmailmessageflow-gen-tests/WorkMailMessageFlowIncludeTests.cpp b/generated/tests/workmailmessageflow-gen-tests/WorkMailMessageFlowIncludeTests.cpp index 153ff2e756e3..5edcab816cc9 100644 --- a/generated/tests/workmailmessageflow-gen-tests/WorkMailMessageFlowIncludeTests.cpp +++ b/generated/tests/workmailmessageflow-gen-tests/WorkMailMessageFlowIncludeTests.cpp @@ -10,9 +10,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/generated/tests/workspaces-gen-tests/WorkSpacesIncludeTests.cpp b/generated/tests/workspaces-gen-tests/WorkSpacesIncludeTests.cpp index 984ccc9f8146..d45ac9d3c4bc 100644 --- a/generated/tests/workspaces-gen-tests/WorkSpacesIncludeTests.cpp +++ b/generated/tests/workspaces-gen-tests/WorkSpacesIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -126,8 +130,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -152,10 +158,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -166,6 +174,7 @@ #include #include #include +#include #include #include #include @@ -207,6 +216,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/workspaces-instances-gen-tests/WorkspacesInstancesIncludeTests.cpp b/generated/tests/workspaces-instances-gen-tests/WorkspacesInstancesIncludeTests.cpp index beb5fe7eec82..90071d668815 100644 --- a/generated/tests/workspaces-instances-gen-tests/WorkspacesInstancesIncludeTests.cpp +++ b/generated/tests/workspaces-instances-gen-tests/WorkspacesInstancesIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -70,12 +74,15 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/generated/tests/workspaces-thin-client-gen-tests/WorkSpacesThinIncludeTestIncludeTests.cpp b/generated/tests/workspaces-thin-client-gen-tests/WorkSpacesThinIncludeTestIncludeTests.cpp index dfd69498a2db..c8881dbcddeb 100644 --- a/generated/tests/workspaces-thin-client-gen-tests/WorkSpacesThinIncludeTestIncludeTests.cpp +++ b/generated/tests/workspaces-thin-client-gen-tests/WorkSpacesThinIncludeTestIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -39,10 +43,13 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/workspaces-web-gen-tests/WorkSpacesWebIncludeTests.cpp b/generated/tests/workspaces-web-gen-tests/WorkSpacesWebIncludeTests.cpp index ff90a8fb3d51..929371b76e3a 100644 --- a/generated/tests/workspaces-web-gen-tests/WorkSpacesWebIncludeTests.cpp +++ b/generated/tests/workspaces-web-gen-tests/WorkSpacesWebIncludeTests.cpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -146,30 +150,42 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include diff --git a/generated/tests/xray-gen-tests/XRayIncludeTests.cpp b/generated/tests/xray-gen-tests/XRayIncludeTests.cpp index e9d5570c1e92..b38ee62f4374 100644 --- a/generated/tests/xray-gen-tests/XRayIncludeTests.cpp +++ b/generated/tests/xray-gen-tests/XRayIncludeTests.cpp @@ -7,17 +7,22 @@ #include #include +#include #include #include #include +#include #include #include +#include #include +#include #include #include #include #include #include +#include #include #include #include @@ -50,34 +55,43 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -97,10 +111,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include From bdffa4d2f252ed0e804bd69dbe6e743f8422922b Mon Sep 17 00:00:00 2001 From: sbaluja Date: Fri, 14 Aug 2026 00:26:00 -0400 Subject: [PATCH 18/19] Use Smithy walker instead of manual BFS --- .../generators/model/CppTypeMapper.java | 40 +++----------- .../model/transforms/GlobalTransforms.java | 53 ++++++------------- 2 files changed, 21 insertions(+), 72 deletions(-) diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java index 3bc53142054e..12d7e3ce8cd2 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/CppTypeMapper.java @@ -5,6 +5,7 @@ package com.amazonaws.util.awsclientsmithygenerator.generators.model; import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.neighbor.Walker; import software.amazon.smithy.model.shapes.ListShape; import software.amazon.smithy.model.shapes.MapShape; import software.amazon.smithy.model.shapes.MemberShape; @@ -15,10 +16,7 @@ import software.amazon.smithy.model.traits.SensitiveTrait; import software.amazon.smithy.model.traits.SparseTrait; -import java.util.ArrayDeque; import java.util.ArrayList; -import java.util.Deque; -import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; @@ -395,42 +393,16 @@ private static boolean isAggregate(Shape shape) { } /** - * Mirrors C2J's {@code Shape.isMutuallyReferencedWith}: true when {@code a} and {@code b} are - * distinct aggregate shapes and each is reachable from the other through the member graph, - * descending one level transparently through list containers (not maps). + * True when {@code a} and {@code b} are distinct aggregate shapes that each reach the other + * through the shape graph (a reference cycle). */ private static boolean isMutuallyReferenced(Shape a, Shape b, Model model) { if (a.getId().equals(b.getId()) || !isAggregate(a) || !isAggregate(b)) { return false; } - return reachableAggregates(a, model).contains(b.getId()) - && reachableAggregates(b, model).contains(a.getId()); - } - - private static Set reachableAggregates(Shape root, Model model) { - Set reachable = new HashSet<>(); - Set visited = new HashSet<>(); - Deque stack = new ArrayDeque<>(); - stack.push(root); - visited.add(root.getId()); - while (!stack.isEmpty()) { - Shape current = stack.pop(); - for (MemberShape member : current.getAllMembers().values()) { - // C2J descends one level through a list container (list -> element), treating the - // list edge as transparent; it does not descend through maps. - Shape target = model.expectShape(member.getTarget()); - if (target.isListShape()) { - target = model.expectShape(target.asListShape().get().getMember().getTarget()); - } - if (isAggregate(target)) { - reachable.add(target.getId()); - if (visited.add(target.getId())) { - stack.push(target); - } - } - } - } - return reachable; + Walker walker = new Walker(model); + return walker.walkShapeIds(a).contains(b.getId()) + && walker.walkShapeIds(b).contains(a.getId()); } } diff --git a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/transforms/GlobalTransforms.java b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/transforms/GlobalTransforms.java index 22e4a816a761..587e926d0474 100644 --- a/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/transforms/GlobalTransforms.java +++ b/tools/code-generation/smithy/cpp-codegen/smithy-cpp-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/model/transforms/GlobalTransforms.java @@ -9,6 +9,7 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.model.ProtocolResolver.Protocol; import software.amazon.smithy.model.Model; import software.amazon.smithy.model.knowledge.TopDownIndex; +import software.amazon.smithy.model.neighbor.Walker; import software.amazon.smithy.model.shapes.ListShape; import software.amazon.smithy.model.shapes.MapShape; import software.amazon.smithy.model.shapes.MemberShape; @@ -21,9 +22,7 @@ import software.amazon.smithy.model.traits.RequiredTrait; import software.amazon.smithy.model.transform.ModelTransformer; -import java.util.ArrayDeque; import java.util.ArrayList; -import java.util.Deque; import java.util.HashSet; import java.util.List; import java.util.Optional; @@ -88,53 +87,31 @@ public static Optional getReservedMemberRename(String memberName, String } /** - * Computes the set of shape IDs reachable from service operations. - * Only reachable shapes should generate model files. - * - * Traversal starts from operation inputs, outputs, and errors, then walks - * structure members, list members, and map keys/values transitively. + * Computes the set of shape IDs reachable from the service's operations; only these shapes + * generate model files. Roots are each operation's input (including {@code smithy.api#Unit} + * for input-less operations), output, and error shapes, from which {@link Walker} walks the + * shape graph transitively. Each root id is included even when its shape is absent from the model. * * @param model the Smithy model * @param service the service shape whose operations define the root set * @return set of ShapeIds reachable from the service's operations */ public static Set computeReachableShapes(Model model, ServiceShape service) { + Walker walker = new Walker(model); Set reachable = new HashSet<>(); - TopDownIndex index = TopDownIndex.of(model); - Deque queue = new ArrayDeque<>(); - - // Seed queue with all operation input/output/error shapes. Use getInputShape() - // so no-input operations (input target smithy.api#Unit) stay reachable, keeping - // the classifier and reachability set in agreement. The BFS below null-guards via - // model.getShape(id).ifPresent(...), so a possibly-absent Unit id is safe to add. - for (OperationShape op : index.getContainedOperations(service)) { - queue.add(op.getInputShape()); - op.getOutput().ifPresent(queue::add); - op.getErrors().forEach(queue::add); - } - - // BFS traversal - while (!queue.isEmpty()) { - ShapeId id = queue.poll(); - if (!reachable.add(id)) continue; - model.getShape(id).ifPresent(shape -> { - if (shape.isStructureShape() || shape.isUnionShape()) { - for (MemberShape member : shape.getAllMembers().values()) { - queue.add(member.getTarget()); - } - } else if (shape.isListShape()) { - shape.asListShape().ifPresent(l -> queue.add(l.getMember().getTarget())); - } else if (shape.isMapShape()) { - shape.asMapShape().ifPresent(m -> { - queue.add(m.getKey().getTarget()); - queue.add(m.getValue().getTarget()); - }); - } - }); + for (OperationShape op : TopDownIndex.of(model).getContainedOperations(service)) { + addReachableFrom(op.getInputShape(), walker, model, reachable); + op.getOutput().ifPresent(id -> addReachableFrom(id, walker, model, reachable)); + op.getErrors().forEach(id -> addReachableFrom(id, walker, model, reachable)); } return reachable; } + private static void addReachableFrom(ShapeId root, Walker walker, Model model, Set out) { + out.add(root); + model.getShape(root).ifPresent(shape -> out.addAll(walker.walkShapeIds(shape))); + } + /** * Returns this class as a ModelTransform. * From 40f2a66b8c0f94b8ea82dbd76215da486040ccbb Mon Sep 17 00:00:00 2001 From: sbaluja Date: Fri, 14 Aug 2026 12:26:53 -0400 Subject: [PATCH 19/19] updated include tests after rebase --- generated/tests/acm-gen-tests/ACMIncludeTests.cpp | 3 +++ .../tests/codecommit-gen-tests/CodeCommitIncludeTests.cpp | 1 + .../securityagent-gen-tests/SecurityAgentIncludeTests.cpp | 1 + 3 files changed, 5 insertions(+) diff --git a/generated/tests/acm-gen-tests/ACMIncludeTests.cpp b/generated/tests/acm-gen-tests/ACMIncludeTests.cpp index f4fe79029d08..b7949bbce9b4 100644 --- a/generated/tests/acm-gen-tests/ACMIncludeTests.cpp +++ b/generated/tests/acm-gen-tests/ACMIncludeTests.cpp @@ -117,6 +117,9 @@ #include #include #include +#include +#include +#include #include #include #include diff --git a/generated/tests/codecommit-gen-tests/CodeCommitIncludeTests.cpp b/generated/tests/codecommit-gen-tests/CodeCommitIncludeTests.cpp index 458abafdca3d..c67cf3512948 100644 --- a/generated/tests/codecommit-gen-tests/CodeCommitIncludeTests.cpp +++ b/generated/tests/codecommit-gen-tests/CodeCommitIncludeTests.cpp @@ -102,6 +102,7 @@ #include #include #include +#include #include #include #include diff --git a/generated/tests/securityagent-gen-tests/SecurityAgentIncludeTests.cpp b/generated/tests/securityagent-gen-tests/SecurityAgentIncludeTests.cpp index 03e751b512ba..994fcf1dd81e 100644 --- a/generated/tests/securityagent-gen-tests/SecurityAgentIncludeTests.cpp +++ b/generated/tests/securityagent-gen-tests/SecurityAgentIncludeTests.cpp @@ -193,6 +193,7 @@ #include #include #include +#include #include #include #include