From 4bcebc25c7a0bab4a9ab047cda18cd7deba87d6d Mon Sep 17 00:00:00 2001 From: kai lin Date: Tue, 13 Jan 2026 14:44:20 -0500 Subject: [PATCH 01/46] Smithy code gen for pagination --- .../include/aws/s3/S3ClientPagination.h | 25 +++++ .../pagination/ListBucketsPaginationTraits.h | 44 +++++++++ .../ListDirectoryBucketsPaginationTraits.h | 44 +++++++++ .../ListObjectsV2PaginationTraits.h | 44 +++++++++ .../pagination/ListPartsPaginationTraits.h | 44 +++++++++ .../cpp-pagination-codegen/build.gradle.kts | 17 ++++ .../awsclientsmithygenerator/CppWriter.java | 38 ++++++++ .../CppWriterDelegator.java | 37 +++++++ .../generators/PaginationCodegenPlugin.java | 22 +++++ .../generators/PaginationData.java | 32 ++++++ .../generators/PaginationHeaderWriter.java | 97 +++++++++++++++++++ .../generators/PaginationParser.java | 60 ++++++++++++ .../generators/PaginationShapeDiscovery.java | 37 +++++++ .../templates/PaginationClientTemplate.java | 71 ++++++++++++++ ...ware.amazon.smithy.build.SmithyBuildPlugin | 1 + .../codegen/cpp-pagination/build.gradle.kts | 77 +++++++++++++++ .../codegen/cpp-pagination/smithy-build.json | 16 +++ .../smithy/codegen/settings.gradle.kts | 2 + tools/scripts/codegen/pagination_gen.py | 95 ++++++++++++++++++ tools/scripts/run_code_generation.py | 8 ++ 20 files changed, 811 insertions(+) create mode 100644 generated/src/aws-cpp-sdk-s3/include/aws/s3/S3ClientPagination.h create mode 100644 generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListBucketsPaginationTraits.h create mode 100644 generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListDirectoryBucketsPaginationTraits.h create mode 100644 generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListObjectsV2PaginationTraits.h create mode 100644 generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/build.gradle.kts create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/CppWriter.java create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/CppWriterDelegator.java create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationData.java create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationShapeDiscovery.java create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientTemplate.java create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/resources/META-INF/services/software.amazon.smithy.build.SmithyBuildPlugin create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination/build.gradle.kts create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination/smithy-build.json create mode 100644 tools/scripts/codegen/pagination_gen.py diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/S3ClientPagination.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/S3ClientPagination.h new file mode 100644 index 000000000000..ff25ee95d87e --- /dev/null +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/S3ClientPagination.h @@ -0,0 +1,25 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once +#include +#include +#include +#include +#include +#include + +namespace Aws +{ +namespace S3 +{ + +using ListBucketsPaginator = Aws::Utils::Pagination::PagePaginator; +using ListDirectoryBucketsPaginator = Aws::Utils::Pagination::PagePaginator; +using ListObjectsV2Paginator = Aws::Utils::Pagination::PagePaginator; +using ListPartsPaginator = Aws::Utils::Pagination::PagePaginator; + +} // namespace S3 +} // namespace Aws diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListBucketsPaginationTraits.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListBucketsPaginationTraits.h new file mode 100644 index 000000000000..5e180a9499c3 --- /dev/null +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListBucketsPaginationTraits.h @@ -0,0 +1,44 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once +#include +#include +#include +#include + +namespace Aws +{ +namespace S3 +{ +namespace Pagination +{ + +struct ListBucketsPaginationTraits +{ + using RequestType = Model::ListBucketsRequest; + using ResultType = Model::ListBucketsResult; + using OutcomeType = Model::ListBucketsOutcome; + using ClientType = S3Client; + + static OutcomeType Invoke(ClientType& client, const RequestType& request) + { + return client.ListBuckets(request); + } + + static bool HasMoreResults(const ResultType& result) + { + return result.GetIsTruncated(); + } + + static void SetNextRequest(const ResultType& result, RequestType& request) + { + request.SetContinuationToken(result.GetContinuationToken()); + } +}; + +} // namespace Pagination +} // namespace S3 +} // namespace Aws diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListDirectoryBucketsPaginationTraits.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListDirectoryBucketsPaginationTraits.h new file mode 100644 index 000000000000..70e0a73c0ffe --- /dev/null +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListDirectoryBucketsPaginationTraits.h @@ -0,0 +1,44 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once +#include +#include +#include +#include + +namespace Aws +{ +namespace S3 +{ +namespace Pagination +{ + +struct ListDirectoryBucketsPaginationTraits +{ + using RequestType = Model::ListDirectoryBucketsRequest; + using ResultType = Model::ListDirectoryBucketsResult; + using OutcomeType = Model::ListDirectoryBucketsOutcome; + using ClientType = S3Client; + + static OutcomeType Invoke(ClientType& client, const RequestType& request) + { + return client.ListDirectoryBuckets(request); + } + + static bool HasMoreResults(const ResultType& result) + { + return result.GetIsTruncated(); + } + + static void SetNextRequest(const ResultType& result, RequestType& request) + { + request.SetContinuationToken(result.GetContinuationToken()); + } +}; + +} // namespace Pagination +} // namespace S3 +} // namespace Aws diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListObjectsV2PaginationTraits.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListObjectsV2PaginationTraits.h new file mode 100644 index 000000000000..14f2129b4494 --- /dev/null +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListObjectsV2PaginationTraits.h @@ -0,0 +1,44 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once +#include +#include +#include +#include + +namespace Aws +{ +namespace S3 +{ +namespace Pagination +{ + +struct ListObjectsV2PaginationTraits +{ + using RequestType = Model::ListObjectsV2Request; + using ResultType = Model::ListObjectsV2Result; + using OutcomeType = Model::ListObjectsV2Outcome; + using ClientType = S3Client; + + static OutcomeType Invoke(ClientType& client, const RequestType& request) + { + return client.ListObjectsV2(request); + } + + static bool HasMoreResults(const ResultType& result) + { + return result.GetIsTruncated(); + } + + static void SetNextRequest(const ResultType& result, RequestType& request) + { + request.SetContinuationToken(result.GetNextContinuationToken()); + } +}; + +} // namespace Pagination +} // namespace S3 +} // namespace Aws diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h new file mode 100644 index 000000000000..d1d78792e6d5 --- /dev/null +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h @@ -0,0 +1,44 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once +#include +#include +#include +#include + +namespace Aws +{ +namespace S3 +{ +namespace Pagination +{ + +struct ListPartsPaginationTraits +{ + using RequestType = Model::ListPartsRequest; + using ResultType = Model::ListPartsResult; + using OutcomeType = Model::ListPartsOutcome; + using ClientType = S3Client; + + static OutcomeType Invoke(ClientType& client, const RequestType& request) + { + return client.ListParts(request); + } + + static bool HasMoreResults(const ResultType& result) + { + return result.GetIsTruncated(); + } + + static void SetNextRequest(const ResultType& result, RequestType& request) + { + request.SetPartNumberMarker(result.GetNextPartNumberMarker()); + } +}; + +} // namespace Pagination +} // namespace S3 +} // namespace Aws diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/build.gradle.kts b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/build.gradle.kts new file mode 100644 index 000000000000..70081533b3ed --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/build.gradle.kts @@ -0,0 +1,17 @@ +plugins { + `java-library` +} + +repositories { + mavenLocal() + mavenCentral() +} + +dependencies { + implementation("software.amazon.smithy:smithy-model:1.51.0") + implementation("software.amazon.smithy:smithy-codegen-core:1.51.0") + implementation("software.amazon.smithy:smithy-aws-traits:1.51.0") + implementation("software.amazon.smithy:smithy-waiters:1.51.0") + implementation("software.amazon.smithy:smithy-rules-engine:1.51.0") + implementation("software.amazon.smithy:smithy-aws-endpoints:1.51.0") +} diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/CppWriter.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/CppWriter.java new file mode 100644 index 000000000000..9317bc0655a8 --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/CppWriter.java @@ -0,0 +1,38 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator; + +import java.util.function.Consumer; + +public class CppWriter { + private final StringBuilder content = new StringBuilder(); + + public void write(String text, Object... args) { + content.append(String.format(text, args)).append("\n"); + } + + public void openBlock(String opener, String closer, Consumer block) { + write(opener); + block.accept(null); + write(closer); + } + + public void writeInclude(String header) { + write("#include <%s>", header); + } + + public void writeNamespaceOpen(String namespace) { + write("namespace %s\n{", namespace); + } + + public void writeNamespaceClose(String namespace) { + write("} // namespace %s", namespace); + } + + @Override + public String toString() { + return content.toString(); + } +} \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/CppWriterDelegator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/CppWriterDelegator.java new file mode 100644 index 000000000000..d2adb93fdc2b --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/CppWriterDelegator.java @@ -0,0 +1,37 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator; + +import software.amazon.smithy.build.FileManifest; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; + +public class CppWriterDelegator { + private final FileManifest fileManifest; + private final Map writers = new HashMap<>(); + + public CppWriterDelegator(FileManifest fileManifest) { + this.fileManifest = fileManifest; + } + + public void useFileWriter(String filename, Consumer writerConsumer) { + CppWriter writer = writers.computeIfAbsent(filename, k -> new CppWriter()); + writerConsumer.accept(writer); + } + + public void flushWriters() { + writers.forEach((filename, writer) -> { + try { + Path outputPath = fileManifest.getBaseDir().resolve(filename); + java.nio.file.Files.createDirectories(outputPath.getParent()); + java.nio.file.Files.writeString(outputPath, writer.toString()); + } catch (Exception e) { + throw new RuntimeException("Failed to write file: " + filename, e); + } + }); + } +} \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java new file mode 100644 index 000000000000..d28917359c15 --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java @@ -0,0 +1,22 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators; + +import software.amazon.smithy.build.PluginContext; +import software.amazon.smithy.build.SmithyBuildPlugin; + +public class PaginationCodegenPlugin implements SmithyBuildPlugin { + + @Override + public String getName() { + return "cpp-codegen-pagination-plugin"; + } + + @Override + public void execute(PluginContext context) { + PaginationParser parser = new PaginationParser(context); + parser.run(); + } +} diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationData.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationData.java new file mode 100644 index 000000000000..d17d7718d865 --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationData.java @@ -0,0 +1,32 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators; + +import software.amazon.smithy.model.shapes.*; +import software.amazon.smithy.model.traits.PaginatedTrait; + +public class PaginationData { + private final OperationShape operation; + private final PaginatedTrait trait; + private final ServiceShape service; + + public PaginationData(OperationShape operation, PaginatedTrait trait, ServiceShape service) { + this.operation = operation; + this.trait = trait; + this.service = service; + } + + public OperationShape getOperation() { + return operation; + } + + public PaginatedTrait getTrait() { + return trait; + } + + public ServiceShape getService() { + return service; + } +} diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java new file mode 100644 index 000000000000..a72b357a328c --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java @@ -0,0 +1,97 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators; + +import software.amazon.smithy.build.PluginContext; +import software.amazon.smithy.codegen.core.SymbolProvider; +import software.amazon.smithy.model.shapes.*; +import software.amazon.smithy.model.traits.PaginatedTrait; +import software.amazon.smithy.aws.traits.ServiceTrait; +import java.nio.file.*; +import java.util.*; + +public class PaginationHeaderWriter { + private final PluginContext context; + private final ServiceShape service; + private final List paginatedOps; + + public PaginationHeaderWriter(PluginContext context, ServiceShape service, List paginatedOps) { + this.context = context; + this.service = service; + this.paginatedOps = paginatedOps; + } + + public void write() { + String serviceName = service.getTrait(ServiceTrait.class) + .map(ServiceTrait::getSdkId) + .orElse(service.getId().getName()) + .replace(" ", "") + .replace("-", ""); + Path outputPath = context.getFileManifest().getBaseDir() + .resolve("include/aws/" + serviceName.toLowerCase() + "/model/pagination"); + + for (PaginationData data : paginatedOps) { + String content = generateTraitsHeader(data, serviceName); + String fileName = data.getOperation().getId().getName() + "PaginationTraits.h"; + + try { + Files.createDirectories(outputPath); + Files.writeString(outputPath.resolve(fileName), content); + } catch (Exception e) { + throw new RuntimeException("Failed to write pagination traits header", e); + } + } + } + + private String generateTraitsHeader(PaginationData data, String serviceName) { + OperationShape op = data.getOperation(); + PaginatedTrait trait = data.getTrait(); + String opName = op.getId().getName(); + + StringBuilder sb = new StringBuilder(); + sb.append("/**\n"); + sb.append(" * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n"); + sb.append(" * SPDX-License-Identifier: Apache-2.0.\n"); + sb.append(" */\n\n"); + sb.append("#pragma once\n"); + sb.append("#include \n"); + sb.append("#include \n"); + sb.append("#include \n"); + sb.append("#include \n\n"); + sb.append("namespace Aws\n{\nnamespace ").append(serviceName).append("\n{\nnamespace Pagination\n{\n\n"); + sb.append("struct ").append(opName).append("PaginationTraits\n{\n"); + sb.append(" using RequestType = Model::").append(opName).append("Request;\n"); + sb.append(" using ResultType = Model::").append(opName).append("Result;\n"); + sb.append(" using OutcomeType = Model::").append(opName).append("Outcome;\n"); + sb.append(" using ClientType = ").append(serviceName).append("Client;\n\n"); + + sb.append(" static OutcomeType Invoke(ClientType& client, const RequestType& request)\n {\n"); + sb.append(" return client.").append(opName).append("(request);\n }\n\n"); + + sb.append(" static bool HasMoreResults(const ResultType& result)\n {\n"); + // Check if there's a truncated field first, otherwise fall back to token check + sb.append(" return result.GetIsTruncated();\n"); + sb.append(" }\n\n"); + + sb.append(" static void SetNextRequest(const ResultType& result, RequestType& request)\n {\n"); + if (trait.getInputToken().isPresent() && trait.getOutputToken().isPresent()) { + String inToken = trait.getInputToken().get(); + String outToken = trait.getOutputToken().get(); + sb.append(" request.Set").append(capitalize(inToken)).append("(result.Get").append(capitalize(outToken)).append("());\n"); + } + sb.append(" }\n"); + + sb.append("};\n\n"); + sb.append("} // namespace Pagination\n"); + sb.append("} // namespace ").append(serviceName).append("\n"); + sb.append("} // namespace Aws\n"); + + return sb.toString(); + } + + private String capitalize(String str) { + return str.substring(0, 1).toUpperCase() + str.substring(1); + } +} diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java new file mode 100644 index 000000000000..f88dcfc1cdf1 --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java @@ -0,0 +1,60 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators; + +import software.amazon.smithy.build.PluginContext; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.*; +import software.amazon.smithy.aws.traits.ServiceTrait; +import com.amazonaws.util.awsclientsmithygenerator.CppWriterDelegator; +import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationClientTemplate; +import java.util.*; + +public class PaginationParser { + private final PluginContext context; + private final Model model; + private final PaginationShapeDiscovery shapeDiscovery; + private final CppWriterDelegator writerDelegator; + + public PaginationParser(PluginContext context) { + this.context = context; + this.model = context.getModel(); + this.shapeDiscovery = new PaginationShapeDiscovery(model); + this.writerDelegator = new CppWriterDelegator(context.getFileManifest()); + } + + public void run() { + for (ServiceShape service : model.getServiceShapes()) { + List paginatedOps = shapeDiscovery.findPaginatedOperations(service); + + if (!paginatedOps.isEmpty()) { + generatePaginationFiles(service, paginatedOps); + } + } + writerDelegator.flushWriters(); + } + + private void generatePaginationFiles(ServiceShape service, List paginatedOps) { + String serviceName = getServiceName(service); + + // Generate client pagination header + writerDelegator.useFileWriter( + "include/aws/" + serviceName.toLowerCase() + "/" + serviceName + "ClientPagination.h", + writer -> new PaginationClientTemplate(service, paginatedOps).render(writer) + ); + + // Generate pagination traits headers + PaginationHeaderWriter headerWriter = new PaginationHeaderWriter(context, service, paginatedOps); + headerWriter.write(); + } + + private String getServiceName(ServiceShape service) { + return service.getTrait(ServiceTrait.class) + .map(ServiceTrait::getSdkId) + .orElse(service.getId().getName()) + .replace(" ", "") + .replace("-", ""); + } +} diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationShapeDiscovery.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationShapeDiscovery.java new file mode 100644 index 000000000000..14f5b67c143a --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationShapeDiscovery.java @@ -0,0 +1,37 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators; + +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.*; +import software.amazon.smithy.model.traits.PaginatedTrait; +import java.util.*; +import java.util.stream.Collectors; + +public class PaginationShapeDiscovery { + private final Model model; + + public PaginationShapeDiscovery(Model model) { + this.model = model; + } + + public List findPaginatedOperations(ServiceShape service) { + return service.getOperations().stream() + .map(id -> model.expectShape(id, OperationShape.class)) + .filter(op -> op.hasTrait(PaginatedTrait.class)) + .map(op -> new PaginationData(op, op.expectTrait(PaginatedTrait.class), service)) + .collect(Collectors.toList()); + } + + public Set getReferencedStructures(List paginatedOps) { + Set structures = new HashSet<>(); + for (PaginationData data : paginatedOps) { + OperationShape op = data.getOperation(); + structures.add(model.expectShape(op.getInputShape(), StructureShape.class)); + structures.add(model.expectShape(op.getOutputShape(), StructureShape.class)); + } + return structures; + } +} \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientTemplate.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientTemplate.java new file mode 100644 index 000000000000..23ad0d4157c5 --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientTemplate.java @@ -0,0 +1,71 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.templates; + +import com.amazonaws.util.awsclientsmithygenerator.CppWriter; +import com.amazonaws.util.awsclientsmithygenerator.generators.PaginationData; +import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.aws.traits.ServiceTrait; +import java.util.List; + +public class PaginationClientTemplate { + private final ServiceShape service; + private final List paginatedOps; + + public PaginationClientTemplate(ServiceShape service, List paginatedOps) { + this.service = service; + this.paginatedOps = paginatedOps; + } + + public void render(CppWriter writer) { + String serviceName = getServiceName(); + + // Header and includes + writer.write("/**"); + writer.write(" * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved."); + writer.write(" * SPDX-License-Identifier: Apache-2.0."); + writer.write(" */"); + writer.write(""); + writer.write("#pragma once"); + + renderIncludes(writer, serviceName); + renderNamespaces(writer, serviceName); + } + + private void renderIncludes(CppWriter writer, String serviceName) { + writer.writeInclude("aws/" + serviceName.toLowerCase() + "/" + serviceName + "Client.h"); + writer.writeInclude("aws/core/utils/pagination/Paginator.h"); + + for (PaginationData data : paginatedOps) { + String opName = data.getOperation().getId().getName(); + writer.writeInclude("aws/" + serviceName.toLowerCase() + "/model/pagination/" + opName + "PaginationTraits.h"); + } + writer.write(""); + } + + private void renderNamespaces(CppWriter writer, String serviceName) { + writer.writeNamespaceOpen("Aws"); + writer.writeNamespaceOpen(serviceName); + writer.write(""); + + for (PaginationData data : paginatedOps) { + String opName = data.getOperation().getId().getName(); + writer.write("using %sPaginator = Aws::Utils::Pagination::PagePaginator<%sClient, Model::%sRequest, Pagination::%sPaginationTraits>;", + opName, serviceName, opName, opName); + } + + writer.write(""); + writer.writeNamespaceClose(serviceName); + writer.writeNamespaceClose("Aws"); + } + + private String getServiceName() { + return service.getTrait(ServiceTrait.class) + .map(ServiceTrait::getSdkId) + .orElse(service.getId().getName()) + .replace(" ", "") + .replace("-", ""); + } +} \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/resources/META-INF/services/software.amazon.smithy.build.SmithyBuildPlugin b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/resources/META-INF/services/software.amazon.smithy.build.SmithyBuildPlugin new file mode 100644 index 000000000000..f4e064860447 --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/resources/META-INF/services/software.amazon.smithy.build.SmithyBuildPlugin @@ -0,0 +1 @@ +com.amazonaws.util.awsclientsmithygenerator.generators.PaginationCodegenPlugin diff --git a/tools/code-generation/smithy/codegen/cpp-pagination/build.gradle.kts b/tools/code-generation/smithy/codegen/cpp-pagination/build.gradle.kts new file mode 100644 index 000000000000..d4a4310418ff --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination/build.gradle.kts @@ -0,0 +1,77 @@ +import software.amazon.smithy.model.Model +import software.amazon.smithy.model.node.Node +import software.amazon.smithy.model.shapes.ServiceShape +import software.amazon.smithy.aws.traits.ServiceTrait +import org.gradle.api.logging.Logging +import kotlin.streams.toList + +val logger = Logging.getLogger("MyLogger") + +plugins { + id("java-library") + id("software.amazon.smithy.gradle.smithy-base").version("1.3.0") +} + +repositories { + mavenLocal() + mavenCentral() +} + +buildscript { + dependencies { + classpath(codegen.model) + classpath(codegen.aws.traits) + classpath(codegen.rules.engine) + } +} + +dependencies { + implementation(project(":cpp-pagination-codegen")) + implementation(codegen.aws.traits) + implementation(codegen.waiters) +} + +tasks.jar { + enabled = false +} + +tasks.register("generate-smithy-build") { + doLast { + val projectionsBuilder = Node.objectNodeBuilder() + val models = project.file("../../api-descriptions") + val filteredServices: String = project.findProperty("servicesFilter")?.toString() ?: "" + val filteredServiceList = filteredServices.split(",").map { it.trim() }.filter { it.isNotEmpty() } + val c2jMapStr: String = project.findProperty("c2jMap")?.toString() ?: "" + + fileTree(models).filter { it.isFile }.files.forEach eachFile@{ file -> + val model = Model.assembler().addImport(file.absolutePath).assemble().result.get() + val services = model.shapes(ServiceShape::class.java).sorted().toList() + if (services.size != 1) return@eachFile + + val service = services[0] + val serviceTrait = service.getTrait(ServiceTrait::class.java).get() + val sdkId = serviceTrait.sdkId.replace(" ", "-").replace("_", "-").lowercase() + + if (filteredServiceList.isNotEmpty() && sdkId !in filteredServiceList) return@eachFile + + val projectionContents = Node.objectNodeBuilder() + .withMember("imports", Node.fromStrings("${models.absolutePath}${File.separator}${file.name}")) + .withMember("plugins", Node.objectNode() + .withMember("cpp-codegen-pagination-plugin", Node.objectNodeBuilder() + .withMember("c2jMap", Node.from(c2jMapStr)) + .build())) + .build() + + projectionsBuilder.withMember("$sdkId.${service.version.lowercase()}", projectionContents) + } + + val outputDirectoryArg = project.findProperty("outputDirectory")?.toString() ?: "output" + file("smithy-build.json").writeText(Node.prettyPrintJson(Node.objectNodeBuilder() + .withMember("version", "1.0") + .withMember("projections", projectionsBuilder.build()) + .withMember("outputDirectory", outputDirectoryArg) + .build())) + } +} + +tasks["build"].dependsOn(tasks["generate-smithy-build"]) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination/smithy-build.json b/tools/code-generation/smithy/codegen/cpp-pagination/smithy-build.json new file mode 100644 index 000000000000..a3adf6fee9d5 --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination/smithy-build.json @@ -0,0 +1,16 @@ +{ + "version": "1.0", + "projections": { + "s3.2006-03-01": { + "imports": [ + "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/s3.json" + ], + "plugins": { + "cpp-codegen-pagination-plugin": { + "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service \": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" + } + } + } + }, + "outputDirectory": "output" +} \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/settings.gradle.kts b/tools/code-generation/smithy/codegen/settings.gradle.kts index bc2b770a2730..e14d59a763f9 100644 --- a/tools/code-generation/smithy/codegen/settings.gradle.kts +++ b/tools/code-generation/smithy/codegen/settings.gradle.kts @@ -2,6 +2,8 @@ rootProject.name = "smithy_code_generation" include("cpp-smoke-tests") include("cpp-smoke-tests-codegen") +include("cpp-pagination-codegen") +include("cpp-pagination") pluginManagement { repositories { diff --git a/tools/scripts/codegen/pagination_gen.py b/tools/scripts/codegen/pagination_gen.py new file mode 100644 index 000000000000..34a828d2f433 --- /dev/null +++ b/tools/scripts/codegen/pagination_gen.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python3 + +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0. + +""" +Wrapper for Smithy pagination generator +""" +import json +import os +import shutil +import subprocess +from typing import List + +SMITHY_GENERATOR_LOCATION = "tools/code-generation/smithy/codegen" +SMITHY_TO_C2J_MAP_FILE = "tools/code-generation/smithy/codegen/smithy2c2j_service_map.json" + + +class PaginationGen(object): + """Wrapper for Smithy pagination generator for C++ SDK""" + + def __init__(self, debug: bool, **kwargs): + self.debug = debug + with open(os.path.abspath(SMITHY_TO_C2J_MAP_FILE), 'r') as file: + self.smithy_c2j_data = json.load(file) + self.c2j_smithy_data = {value: key for key, value in self.smithy_c2j_data.items()} + + def generate(self, clients_to_build: set): + """Generate pagination APIs for SDK clients""" + smithy_services = [self.c2j_smithy_data.get(service, service) for service in clients_to_build] + print(f"Generating pagination for: {','.join(smithy_services)}") + + if self._generate_pagination(smithy_services, json.dumps(self.smithy_c2j_data)): + self._copy_cpp_codegen_contents( + os.path.abspath("tools/code-generation/smithy/codegen"), + "cpp-codegen-pagination-plugin", + os.path.abspath("generated/src") + ) + return 0 + return -1 + + def _generate_pagination(self, smithy_services: List[str], smithy_c2j_data: str): + smithy_codegen_command = [ + "./gradlew", + ":cpp-pagination:build", + "-PservicesFilter=" + ",".join(smithy_services), + "-Pc2jMap=" + smithy_c2j_data + ] + + try: + if self.debug: + print(f"RUNNING: {' '.join(smithy_codegen_command)}\nFROM: {SMITHY_GENERATOR_LOCATION}") + + process = subprocess.run( + smithy_codegen_command, + timeout=6*60, + check=True, + capture_output=True, + text=True, + cwd=SMITHY_GENERATOR_LOCATION + ) + print("Pagination codegen successful!\n", process.stdout) + return True + + except subprocess.CalledProcessError as e: + print(f"Command failed: {e.returncode}\nError: {e.stderr}") + return False + + def _copy_cpp_codegen_contents(self, top_level_dir: str, plugin_name: str, target_dir: str): + for root, dirs, files in os.walk(top_level_dir): + if plugin_name in dirs: + source_dir = os.path.join(root, plugin_name) + + # Extract service name from the projection directory + projection_dir = os.path.basename(os.path.dirname(source_dir)) + service_name = projection_dir.split('.')[0] # e.g., "s3.2006-03-01" -> "s3" + + service_target_dir = os.path.join(target_dir, f"aws-cpp-sdk-{service_name}") + os.makedirs(service_target_dir, exist_ok=True) + + for item in os.listdir(source_dir): + source_item = os.path.join(source_dir, item) + target_item = os.path.join(service_target_dir, item) + if os.path.isdir(source_item): + shutil.copytree(source_item, target_item, dirs_exist_ok=True) + else: + shutil.copy2(source_item, target_item) + print(f"Copied from '{source_dir}' to '{service_target_dir}'") + + # Cleanup output directory + output_dir = os.path.join(top_level_dir, "cpp-pagination/output") + if os.path.exists(output_dir): + shutil.rmtree(output_dir) + print(f"Cleaned up '{output_dir}'") + diff --git a/tools/scripts/run_code_generation.py b/tools/scripts/run_code_generation.py index 014ee39ce3dc..69e431675b34 100644 --- a/tools/scripts/run_code_generation.py +++ b/tools/scripts/run_code_generation.py @@ -13,6 +13,7 @@ from codegen.model_utils import ModelUtils from codegen.protocol_tests_gen import ProtocolTestsGen from codegen.smoke_tests_gen import SmokeTestsGen +from codegen.pagination_gen import PaginationGen def parse_arguments() -> dict: @@ -154,6 +155,13 @@ def main(): # generate code using smithy for all discoverable clients # clients_to_build check is present because user can generate only defaults or partitions or protocol-tests clients_to_build = model_utils.get_clients_to_build() + + if clients_to_build: + pagination_gen = PaginationGen(args["debug"]) + if pagination_gen.generate(clients_to_build) != 0: + print("ERROR: Failed to generate pagination!") + return -1 + 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 5fd2410e148a56b19d50bbc9c5e10d0195a00fca Mon Sep 17 00:00:00 2001 From: kai lin Date: Tue, 13 Jan 2026 14:44:20 -0500 Subject: [PATCH 02/46] Smithy code gen for pagination --- .../include/aws/s3/S3ClientPagination.h | 21 ++++----- .../pagination/ListBucketsPaginationTraits.h | 45 +++++++------------ .../ListDirectoryBucketsPaginationTraits.h | 45 +++++++------------ .../ListObjectsV2PaginationTraits.h | 45 +++++++------------ .../pagination/ListPartsPaginationTraits.h | 45 +++++++------------ .../cpp-pagination-codegen/build.gradle.kts | 1 + .../codegen/cpp-pagination/build.gradle.kts | 16 +++++-- tools/scripts/codegen/legacy_c2j_cpp_gen.py | 7 --- tools/scripts/codegen/pagination_gen.py | 16 ++++--- tools/scripts/run_code_generation.py | 8 ++++ 10 files changed, 112 insertions(+), 137 deletions(-) diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/S3ClientPagination.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/S3ClientPagination.h index ff25ee95d87e..9afd5a3e9908 100644 --- a/generated/src/aws-cpp-sdk-s3/include/aws/s3/S3ClientPagination.h +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/S3ClientPagination.h @@ -4,22 +4,23 @@ */ #pragma once -#include #include +#include #include #include #include #include -namespace Aws -{ -namespace S3 -{ +namespace Aws { +namespace S3 { -using ListBucketsPaginator = Aws::Utils::Pagination::PagePaginator; -using ListDirectoryBucketsPaginator = Aws::Utils::Pagination::PagePaginator; -using ListObjectsV2Paginator = Aws::Utils::Pagination::PagePaginator; +using ListBucketsPaginator = + Aws::Utils::Pagination::PagePaginator; +using ListDirectoryBucketsPaginator = + Aws::Utils::Pagination::PagePaginator; +using ListObjectsV2Paginator = + Aws::Utils::Pagination::PagePaginator; using ListPartsPaginator = Aws::Utils::Pagination::PagePaginator; -} // namespace S3 -} // namespace Aws +} // namespace S3 +} // namespace Aws diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListBucketsPaginationTraits.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListBucketsPaginationTraits.h index 5e180a9499c3..b59c4d30577a 100644 --- a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListBucketsPaginationTraits.h +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListBucketsPaginationTraits.h @@ -4,41 +4,30 @@ */ #pragma once +#include #include #include #include -#include -namespace Aws -{ -namespace S3 -{ -namespace Pagination -{ +namespace Aws { +namespace S3 { +namespace Pagination { -struct ListBucketsPaginationTraits -{ - using RequestType = Model::ListBucketsRequest; - using ResultType = Model::ListBucketsResult; - using OutcomeType = Model::ListBucketsOutcome; - using ClientType = S3Client; +struct ListBucketsPaginationTraits { + using RequestType = Model::ListBucketsRequest; + using ResultType = Model::ListBucketsResult; + using OutcomeType = Model::ListBucketsOutcome; + using ClientType = S3Client; - static OutcomeType Invoke(ClientType& client, const RequestType& request) - { - return client.ListBuckets(request); - } + static OutcomeType Invoke(ClientType& client, const RequestType& request) { return client.ListBuckets(request); } - static bool HasMoreResults(const ResultType& result) - { - return result.GetIsTruncated(); - } + static bool HasMoreResults(const ResultType& result) { return result.GetIsTruncated(); } - static void SetNextRequest(const ResultType& result, RequestType& request) - { - request.SetContinuationToken(result.GetContinuationToken()); - } + static void SetNextRequest(const ResultType& result, RequestType& request) { + request.SetContinuationToken(result.GetContinuationToken()); + } }; -} // namespace Pagination -} // namespace S3 -} // namespace Aws +} // namespace Pagination +} // namespace S3 +} // namespace Aws diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListDirectoryBucketsPaginationTraits.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListDirectoryBucketsPaginationTraits.h index 70e0a73c0ffe..42696009e483 100644 --- a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListDirectoryBucketsPaginationTraits.h +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListDirectoryBucketsPaginationTraits.h @@ -4,41 +4,30 @@ */ #pragma once +#include #include #include #include -#include -namespace Aws -{ -namespace S3 -{ -namespace Pagination -{ +namespace Aws { +namespace S3 { +namespace Pagination { -struct ListDirectoryBucketsPaginationTraits -{ - using RequestType = Model::ListDirectoryBucketsRequest; - using ResultType = Model::ListDirectoryBucketsResult; - using OutcomeType = Model::ListDirectoryBucketsOutcome; - using ClientType = S3Client; +struct ListDirectoryBucketsPaginationTraits { + using RequestType = Model::ListDirectoryBucketsRequest; + using ResultType = Model::ListDirectoryBucketsResult; + using OutcomeType = Model::ListDirectoryBucketsOutcome; + using ClientType = S3Client; - static OutcomeType Invoke(ClientType& client, const RequestType& request) - { - return client.ListDirectoryBuckets(request); - } + static OutcomeType Invoke(ClientType& client, const RequestType& request) { return client.ListDirectoryBuckets(request); } - static bool HasMoreResults(const ResultType& result) - { - return result.GetIsTruncated(); - } + static bool HasMoreResults(const ResultType& result) { return result.GetIsTruncated(); } - static void SetNextRequest(const ResultType& result, RequestType& request) - { - request.SetContinuationToken(result.GetContinuationToken()); - } + static void SetNextRequest(const ResultType& result, RequestType& request) { + request.SetContinuationToken(result.GetContinuationToken()); + } }; -} // namespace Pagination -} // namespace S3 -} // namespace Aws +} // namespace Pagination +} // namespace S3 +} // namespace Aws diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListObjectsV2PaginationTraits.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListObjectsV2PaginationTraits.h index 14f2129b4494..2874bd1d6093 100644 --- a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListObjectsV2PaginationTraits.h +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListObjectsV2PaginationTraits.h @@ -4,41 +4,30 @@ */ #pragma once +#include #include #include #include -#include -namespace Aws -{ -namespace S3 -{ -namespace Pagination -{ +namespace Aws { +namespace S3 { +namespace Pagination { -struct ListObjectsV2PaginationTraits -{ - using RequestType = Model::ListObjectsV2Request; - using ResultType = Model::ListObjectsV2Result; - using OutcomeType = Model::ListObjectsV2Outcome; - using ClientType = S3Client; +struct ListObjectsV2PaginationTraits { + using RequestType = Model::ListObjectsV2Request; + using ResultType = Model::ListObjectsV2Result; + using OutcomeType = Model::ListObjectsV2Outcome; + using ClientType = S3Client; - static OutcomeType Invoke(ClientType& client, const RequestType& request) - { - return client.ListObjectsV2(request); - } + static OutcomeType Invoke(ClientType& client, const RequestType& request) { return client.ListObjectsV2(request); } - static bool HasMoreResults(const ResultType& result) - { - return result.GetIsTruncated(); - } + static bool HasMoreResults(const ResultType& result) { return result.GetIsTruncated(); } - static void SetNextRequest(const ResultType& result, RequestType& request) - { - request.SetContinuationToken(result.GetNextContinuationToken()); - } + static void SetNextRequest(const ResultType& result, RequestType& request) { + request.SetContinuationToken(result.GetNextContinuationToken()); + } }; -} // namespace Pagination -} // namespace S3 -} // namespace Aws +} // namespace Pagination +} // namespace S3 +} // namespace Aws diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h index d1d78792e6d5..59c47154ef99 100644 --- a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h @@ -4,41 +4,30 @@ */ #pragma once +#include #include #include #include -#include -namespace Aws -{ -namespace S3 -{ -namespace Pagination -{ +namespace Aws { +namespace S3 { +namespace Pagination { -struct ListPartsPaginationTraits -{ - using RequestType = Model::ListPartsRequest; - using ResultType = Model::ListPartsResult; - using OutcomeType = Model::ListPartsOutcome; - using ClientType = S3Client; +struct ListPartsPaginationTraits { + using RequestType = Model::ListPartsRequest; + using ResultType = Model::ListPartsResult; + using OutcomeType = Model::ListPartsOutcome; + using ClientType = S3Client; - static OutcomeType Invoke(ClientType& client, const RequestType& request) - { - return client.ListParts(request); - } + static OutcomeType Invoke(ClientType& client, const RequestType& request) { return client.ListParts(request); } - static bool HasMoreResults(const ResultType& result) - { - return result.GetIsTruncated(); - } + static bool HasMoreResults(const ResultType& result) { return result.GetIsTruncated(); } - static void SetNextRequest(const ResultType& result, RequestType& request) - { - request.SetPartNumberMarker(result.GetNextPartNumberMarker()); - } + static void SetNextRequest(const ResultType& result, RequestType& request) { + request.SetPartNumberMarker(result.GetNextPartNumberMarker()); + } }; -} // namespace Pagination -} // namespace S3 -} // namespace Aws +} // namespace Pagination +} // namespace S3 +} // namespace Aws diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/build.gradle.kts b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/build.gradle.kts index 70081533b3ed..d929cca7cbb1 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/build.gradle.kts +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/build.gradle.kts @@ -14,4 +14,5 @@ dependencies { implementation("software.amazon.smithy:smithy-waiters:1.51.0") implementation("software.amazon.smithy:smithy-rules-engine:1.51.0") implementation("software.amazon.smithy:smithy-aws-endpoints:1.51.0") + implementation("software.amazon.smithy:smithy-aws-iam-traits:1.51.0") } diff --git a/tools/code-generation/smithy/codegen/cpp-pagination/build.gradle.kts b/tools/code-generation/smithy/codegen/cpp-pagination/build.gradle.kts index d4a4310418ff..e6fc1e2a6894 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination/build.gradle.kts +++ b/tools/code-generation/smithy/codegen/cpp-pagination/build.gradle.kts @@ -28,6 +28,11 @@ buildscript { dependencies { implementation(project(":cpp-pagination-codegen")) implementation(codegen.aws.traits) + implementation(codegen.aws.cloudformation.traits) + implementation(codegen.aws.iam.traits) + implementation(codegen.aws.endpoints) + implementation(codegen.smoke.test.traits) + implementation(codegen.aws.smoke.test.model) implementation(codegen.waiters) } @@ -44,9 +49,14 @@ tasks.register("generate-smithy-build") { val c2jMapStr: String = project.findProperty("c2jMap")?.toString() ?: "" fileTree(models).filter { it.isFile }.files.forEach eachFile@{ file -> - val model = Model.assembler().addImport(file.absolutePath).assemble().result.get() - val services = model.shapes(ServiceShape::class.java).sorted().toList() - if (services.size != 1) return@eachFile + val model = Model.assembler() + .addImport(file.absolutePath) + // Grab the result directly rather than worrying about checking for errors via unwrap. + // All we care about here is the service shape, any unchecked errors will be exposed + // as part of the actual build task done by the smithy gradle plugin. + .assemble().result.get() + val services = model.shapes(ServiceShape::class.java).sorted().toList() + if (services.size != 1) return@eachFile val service = services[0] val serviceTrait = service.getTrait(ServiceTrait::class.java).get() diff --git a/tools/scripts/codegen/legacy_c2j_cpp_gen.py b/tools/scripts/codegen/legacy_c2j_cpp_gen.py index 7e1df6be35f1..ee77eaa90c4b 100644 --- a/tools/scripts/codegen/legacy_c2j_cpp_gen.py +++ b/tools/scripts/codegen/legacy_c2j_cpp_gen.py @@ -16,7 +16,6 @@ from concurrent.futures import ProcessPoolExecutor, wait, FIRST_COMPLETED, ALL_COMPLETED from pathlib import Path -from codegen.format_util import format_directories from codegen.include_tests_util import IncludeTestsUtil from codegen.model_utils import ServiceModel @@ -149,12 +148,6 @@ def generate(self, executor: ProcessPoolExecutor, max_workers: int, args: dict) print(f"Code generation done, (re)generated {len(done)} packages.") # Including defaults and partitions - # Format generated client code - generated_clients = [service for service in self.c2j_models.keys()] - if generated_clients: - client_dirs = [f"{self.output_location}/src/aws-cpp-sdk-{client}" for client in generated_clients] - format_directories(client_dirs) - return 0 def _init_common_java_cli(self, diff --git a/tools/scripts/codegen/pagination_gen.py b/tools/scripts/codegen/pagination_gen.py index 34a828d2f433..503faaa6a388 100644 --- a/tools/scripts/codegen/pagination_gen.py +++ b/tools/scripts/codegen/pagination_gen.py @@ -28,13 +28,15 @@ def __init__(self, debug: bool, **kwargs): def generate(self, clients_to_build: set): """Generate pagination APIs for SDK clients""" smithy_services = [self.c2j_smithy_data.get(service, service) for service in clients_to_build] - print(f"Generating pagination for: {','.join(smithy_services)}") + if self.debug: + print(f"Generating pagination for: {','.join(smithy_services)}") if self._generate_pagination(smithy_services, json.dumps(self.smithy_c2j_data)): + target_dir = os.path.abspath("generated/src") self._copy_cpp_codegen_contents( os.path.abspath("tools/code-generation/smithy/codegen"), "cpp-codegen-pagination-plugin", - os.path.abspath("generated/src") + target_dir ) return 0 return -1 @@ -59,7 +61,9 @@ def _generate_pagination(self, smithy_services: List[str], smithy_c2j_data: str) text=True, cwd=SMITHY_GENERATOR_LOCATION ) - print("Pagination codegen successful!\n", process.stdout) + print("Pagination codegen successful!") + if self.debug: + print(process.stdout) return True except subprocess.CalledProcessError as e: @@ -85,11 +89,13 @@ def _copy_cpp_codegen_contents(self, top_level_dir: str, plugin_name: str, targe shutil.copytree(source_item, target_item, dirs_exist_ok=True) else: shutil.copy2(source_item, target_item) - print(f"Copied from '{source_dir}' to '{service_target_dir}'") + if self.debug: + print(f"Copied from '{source_dir}' to '{service_target_dir}'") # Cleanup output directory output_dir = os.path.join(top_level_dir, "cpp-pagination/output") if os.path.exists(output_dir): shutil.rmtree(output_dir) - print(f"Cleaned up '{output_dir}'") + if self.debug: + print(f"Cleaned up '{output_dir}'") diff --git a/tools/scripts/run_code_generation.py b/tools/scripts/run_code_generation.py index 69e431675b34..b88ee081179e 100644 --- a/tools/scripts/run_code_generation.py +++ b/tools/scripts/run_code_generation.py @@ -14,6 +14,7 @@ from codegen.protocol_tests_gen import ProtocolTestsGen from codegen.smoke_tests_gen import SmokeTestsGen from codegen.pagination_gen import PaginationGen +from codegen.format_util import format_directories def parse_arguments() -> dict: @@ -168,6 +169,13 @@ def main(): print("ERROR: Failed to generate smoke test(s)!") return -1 + # Format all generated C++ code at the end + if clients_to_build: + client_dirs = [f"{args['output_location']}/src/aws-cpp-sdk-{client}" for client in clients_to_build] + existing_dirs = [d for d in client_dirs if os.path.exists(d)] + if existing_dirs: + format_directories(existing_dirs) + return 0 From f6b745f174df801d3c1da34ff14a2c76d28970d7 Mon Sep 17 00:00:00 2001 From: kai lin Date: Wed, 14 Jan 2026 14:57:37 -0500 Subject: [PATCH 03/46] updated parser to use c2j mapping names --- .../generators/PaginationParser.java | 31 ++++++++++++++++++- tools/scripts/codegen/pagination_gen.py | 8 +++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java index f88dcfc1cdf1..05116306ce28 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java @@ -6,6 +6,8 @@ import software.amazon.smithy.build.PluginContext; import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.node.Node; +import software.amazon.smithy.model.node.ObjectNode; import software.amazon.smithy.model.shapes.*; import software.amazon.smithy.aws.traits.ServiceTrait; import com.amazonaws.util.awsclientsmithygenerator.CppWriterDelegator; @@ -17,12 +19,27 @@ public class PaginationParser { private final Model model; private final PaginationShapeDiscovery shapeDiscovery; private final CppWriterDelegator writerDelegator; + private Map c2jMap; public PaginationParser(PluginContext context) { this.context = context; this.model = context.getModel(); this.shapeDiscovery = new PaginationShapeDiscovery(model); this.writerDelegator = new CppWriterDelegator(context.getFileManifest()); + + // Initialize c2j map + this.c2jMap = new HashMap<>(); + ObjectNode settings = context.getSettings(); + if (settings.containsMember("c2jMap")) { + Node c2jMapNode = settings.expectMember("c2jMap"); + if (c2jMapNode.isStringNode()) { + String jsonStr = c2jMapNode.expectStringNode().getValue(); + ObjectNode mapNode = Node.parseJsonWithComments(jsonStr).expectObjectNode(); + mapNode.getMembers().forEach((key, value) -> { + this.c2jMap.put(key.getValue(), value.expectStringNode().getValue()); + }); + } + } } public void run() { @@ -38,10 +55,11 @@ public void run() { private void generatePaginationFiles(ServiceShape service, List paginatedOps) { String serviceName = getServiceName(service); + String c2jServiceName = getC2jServiceName(service); // Generate client pagination header writerDelegator.useFileWriter( - "include/aws/" + serviceName.toLowerCase() + "/" + serviceName + "ClientPagination.h", + "include/aws/" + c2jServiceName + "/" + serviceName + "ClientPagination.h", writer -> new PaginationClientTemplate(service, paginatedOps).render(writer) ); @@ -57,4 +75,15 @@ private String getServiceName(ServiceShape service) { .replace(" ", "") .replace("-", ""); } + + private String getC2jServiceName(ServiceShape service) { + String sdkId = service.getTrait(ServiceTrait.class) + .map(ServiceTrait::getSdkId) + .orElse(service.getId().getName()) + .trim() + .toLowerCase() + .replace(" ", "-"); + + return c2jMap.getOrDefault(sdkId, sdkId); + } } diff --git a/tools/scripts/codegen/pagination_gen.py b/tools/scripts/codegen/pagination_gen.py index 503faaa6a388..1a5b7704ee26 100644 --- a/tools/scripts/codegen/pagination_gen.py +++ b/tools/scripts/codegen/pagination_gen.py @@ -64,6 +64,7 @@ def _generate_pagination(self, smithy_services: List[str], smithy_c2j_data: str) print("Pagination codegen successful!") if self.debug: print(process.stdout) + print(f"Pagination generation done, (re)generated {len(smithy_services)} package(s).") return True except subprocess.CalledProcessError as e: @@ -77,9 +78,12 @@ def _copy_cpp_codegen_contents(self, top_level_dir: str, plugin_name: str, targe # Extract service name from the projection directory projection_dir = os.path.basename(os.path.dirname(source_dir)) - service_name = projection_dir.split('.')[0] # e.g., "s3.2006-03-01" -> "s3" + smithy_service_name = projection_dir.split('.')[0] # e.g., "api-gateway.2017-11-27" -> "api-gateway" - service_target_dir = os.path.join(target_dir, f"aws-cpp-sdk-{service_name}") + # Map to c2j service name + c2j_service_name = self.smithy_c2j_data.get(smithy_service_name, smithy_service_name) + + service_target_dir = os.path.join(target_dir, f"aws-cpp-sdk-{c2j_service_name}") os.makedirs(service_target_dir, exist_ok=True) for item in os.listdir(source_dir): From 2de73f59b01a04b9afde47f101131a45ab41fff0 Mon Sep 17 00:00:00 2001 From: kai lin Date: Wed, 14 Jan 2026 15:53:54 -0500 Subject: [PATCH 04/46] updated writer to use c2j mapping names and deleted space in map.json --- .../generators/PaginationHeaderWriter.java | 14 ++++++++------ .../generators/PaginationParser.java | 2 +- .../smithy/codegen/smithy2c2j_service_map.json | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java index a72b357a328c..09d91faa5965 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java @@ -16,11 +16,13 @@ public class PaginationHeaderWriter { private final PluginContext context; private final ServiceShape service; private final List paginatedOps; + private final String c2jServiceName; - public PaginationHeaderWriter(PluginContext context, ServiceShape service, List paginatedOps) { + public PaginationHeaderWriter(PluginContext context, ServiceShape service, List paginatedOps, String c2jServiceName) { this.context = context; this.service = service; this.paginatedOps = paginatedOps; + this.c2jServiceName = c2jServiceName; } public void write() { @@ -30,7 +32,7 @@ public void write() { .replace(" ", "") .replace("-", ""); Path outputPath = context.getFileManifest().getBaseDir() - .resolve("include/aws/" + serviceName.toLowerCase() + "/model/pagination"); + .resolve("include/aws/" + c2jServiceName + "/model/pagination"); for (PaginationData data : paginatedOps) { String content = generateTraitsHeader(data, serviceName); @@ -56,10 +58,10 @@ private String generateTraitsHeader(PaginationData data, String serviceName) { sb.append(" * SPDX-License-Identifier: Apache-2.0.\n"); sb.append(" */\n\n"); sb.append("#pragma once\n"); - sb.append("#include \n"); - sb.append("#include \n"); - sb.append("#include \n"); - sb.append("#include \n\n"); + sb.append("#include \n"); + sb.append("#include \n"); + sb.append("#include \n"); + sb.append("#include \n\n"); sb.append("namespace Aws\n{\nnamespace ").append(serviceName).append("\n{\nnamespace Pagination\n{\n\n"); sb.append("struct ").append(opName).append("PaginationTraits\n{\n"); sb.append(" using RequestType = Model::").append(opName).append("Request;\n"); diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java index 05116306ce28..45e9f7b58dc7 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java @@ -64,7 +64,7 @@ private void generatePaginationFiles(ServiceShape service, List ); // Generate pagination traits headers - PaginationHeaderWriter headerWriter = new PaginationHeaderWriter(context, service, paginatedOps); + PaginationHeaderWriter headerWriter = new PaginationHeaderWriter(context, service, paginatedOps, c2jServiceName); headerWriter.write(); } diff --git a/tools/code-generation/smithy/codegen/smithy2c2j_service_map.json b/tools/code-generation/smithy/codegen/smithy2c2j_service_map.json index d4865618ff4f..1ff0190e0acb 100644 --- a/tools/code-generation/smithy/codegen/smithy2c2j_service_map.json +++ b/tools/code-generation/smithy/codegen/smithy2c2j_service_map.json @@ -60,7 +60,7 @@ "lex-model-building-service":"lex-models", "cloudwatch-logs":"logs", "directory-service":"ds", - "elasticsearch-service ":"es", + "elasticsearch-service":"es", "importexport":"importexport", "sdb":"sdb", "transcribe-streaming":"transcribestreaming" From 23d324b3d188e76490c0f3d20c6131619d50c8bb Mon Sep 17 00:00:00 2001 From: kai lin Date: Thu, 15 Jan 2026 12:05:53 -0500 Subject: [PATCH 05/46] fix file location --- .../util/awsclientsmithygenerator/{ => generators}/CppWriter.java | 0 .../{ => generators}/CppWriterDelegator.java | 0 .../generators/{ => templates}/PaginationCodegenPlugin.java | 0 .../generators/{ => templates}/PaginationData.java | 0 .../generators/{ => templates}/PaginationHeaderWriter.java | 0 .../generators/{ => templates}/PaginationParser.java | 0 .../generators/{ => templates}/PaginationShapeDiscovery.java | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/{ => generators}/CppWriter.java (100%) rename tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/{ => generators}/CppWriterDelegator.java (100%) rename tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/{ => templates}/PaginationCodegenPlugin.java (100%) rename tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/{ => templates}/PaginationData.java (100%) rename tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/{ => templates}/PaginationHeaderWriter.java (100%) rename tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/{ => templates}/PaginationParser.java (100%) rename tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/{ => templates}/PaginationShapeDiscovery.java (100%) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/CppWriter.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java similarity index 100% rename from tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/CppWriter.java rename to tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/CppWriterDelegator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriterDelegator.java similarity index 100% rename from tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/CppWriterDelegator.java rename to tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriterDelegator.java diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java similarity index 100% rename from tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java rename to tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationData.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationData.java similarity index 100% rename from tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationData.java rename to tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationData.java diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationHeaderWriter.java similarity index 100% rename from tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java rename to tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationHeaderWriter.java diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationParser.java similarity index 100% rename from tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java rename to tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationParser.java diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationShapeDiscovery.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationShapeDiscovery.java similarity index 100% rename from tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationShapeDiscovery.java rename to tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationShapeDiscovery.java From 7037bce192d430a706e5a5a1413e3fe6d3723171 Mon Sep 17 00:00:00 2001 From: kai lin Date: Thu, 15 Jan 2026 14:40:22 -0500 Subject: [PATCH 06/46] added a compilation test --- .../pagination/ListBucketsPaginationTraits.h | 2 +- .../ListDirectoryBucketsPaginationTraits.h | 2 +- .../ListObjectsV2PaginationTraits.h | 2 +- .../pagination/ListPartsPaginationTraits.h | 2 +- .../AllPaginationHeadersCompilationTest.cpp | 28 ++++++++ .../generators/ClientCodegenSettings.java | 20 ++++++ .../generators/CppWriter.java | 5 +- .../generators/CppWriterDelegator.java | 2 +- .../generators/HeaderCompilationParser.java | 65 +++++++++++++++++ .../generators/PaginationCodegenPlugin.java | 45 ++++++++++++ .../{templates => }/PaginationData.java | 2 +- .../PaginationHeaderWriter.java | 18 ++++- .../{templates => }/PaginationParser.java | 20 +++--- .../generators/ShapeUtil.java | 25 +++++++ .../HeaderCompilationCMakeTemplate.java | 42 +++++++++++ .../templates/HeaderCompilationTemplate.java | 70 +++++++++++++++++++ .../templates/PaginationClientTemplate.java | 4 +- .../templates/PaginationCodegenPlugin.java | 22 ------ .../templates/PaginationShapeDiscovery.java | 37 ---------- tools/scripts/codegen/pagination_gen.py | 13 ++++ 20 files changed, 344 insertions(+), 82 deletions(-) create mode 100644 generated/tests/s3-gen-tests/AllPaginationHeadersCompilationTest.cpp create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ClientCodegenSettings.java create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/HeaderCompilationParser.java create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java rename tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/{templates => }/PaginationData.java (91%) rename tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/{templates => }/PaginationHeaderWriter.java (82%) rename tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/{templates => }/PaginationParser.java (83%) create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/HeaderCompilationCMakeTemplate.java create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/HeaderCompilationTemplate.java delete mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java delete mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationShapeDiscovery.java diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListBucketsPaginationTraits.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListBucketsPaginationTraits.h index b59c4d30577a..a3ab75a45a20 100644 --- a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListBucketsPaginationTraits.h +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListBucketsPaginationTraits.h @@ -21,7 +21,7 @@ struct ListBucketsPaginationTraits { static OutcomeType Invoke(ClientType& client, const RequestType& request) { return client.ListBuckets(request); } - static bool HasMoreResults(const ResultType& result) { return result.GetIsTruncated(); } + static bool HasMoreResults(const ResultType& result) { return !result.GetContinuationToken().empty(); } static void SetNextRequest(const ResultType& result, RequestType& request) { request.SetContinuationToken(result.GetContinuationToken()); diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListDirectoryBucketsPaginationTraits.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListDirectoryBucketsPaginationTraits.h index 42696009e483..f7f6de8b6fcc 100644 --- a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListDirectoryBucketsPaginationTraits.h +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListDirectoryBucketsPaginationTraits.h @@ -21,7 +21,7 @@ struct ListDirectoryBucketsPaginationTraits { static OutcomeType Invoke(ClientType& client, const RequestType& request) { return client.ListDirectoryBuckets(request); } - static bool HasMoreResults(const ResultType& result) { return result.GetIsTruncated(); } + static bool HasMoreResults(const ResultType& result) { return !result.GetContinuationToken().empty(); } static void SetNextRequest(const ResultType& result, RequestType& request) { request.SetContinuationToken(result.GetContinuationToken()); diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListObjectsV2PaginationTraits.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListObjectsV2PaginationTraits.h index 2874bd1d6093..718d63337787 100644 --- a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListObjectsV2PaginationTraits.h +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListObjectsV2PaginationTraits.h @@ -21,7 +21,7 @@ struct ListObjectsV2PaginationTraits { static OutcomeType Invoke(ClientType& client, const RequestType& request) { return client.ListObjectsV2(request); } - static bool HasMoreResults(const ResultType& result) { return result.GetIsTruncated(); } + static bool HasMoreResults(const ResultType& result) { return !result.GetNextContinuationToken().empty(); } static void SetNextRequest(const ResultType& result, RequestType& request) { request.SetContinuationToken(result.GetNextContinuationToken()); diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h index 59c47154ef99..dc6a20a510d9 100644 --- a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h @@ -21,7 +21,7 @@ struct ListPartsPaginationTraits { static OutcomeType Invoke(ClientType& client, const RequestType& request) { return client.ListParts(request); } - static bool HasMoreResults(const ResultType& result) { return result.GetIsTruncated(); } + static bool HasMoreResults(const ResultType& result) { return result.GetNextPartNumberMarker() != 0; } static void SetNextRequest(const ResultType& result, RequestType& request) { request.SetPartNumberMarker(result.GetNextPartNumberMarker()); diff --git a/generated/tests/s3-gen-tests/AllPaginationHeadersCompilationTest.cpp b/generated/tests/s3-gen-tests/AllPaginationHeadersCompilationTest.cpp new file mode 100644 index 000000000000..418f96be4ce8 --- /dev/null +++ b/generated/tests/s3-gen-tests/AllPaginationHeadersCompilationTest.cpp @@ -0,0 +1,28 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +// Header compilation test for ALL pagination headers +// This test ensures all generated pagination headers compile successfully + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +class AllPaginationHeadersCompilationTest : public Aws::Testing::AwsCppSdkGTestSuite +{ +}; + +TEST_F(AllPaginationHeadersCompilationTest, AllPaginationHeadersCompile) +{ + // Test passes if compilation succeeds + SUCCEED(); +} diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ClientCodegenSettings.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ClientCodegenSettings.java new file mode 100644 index 000000000000..f992d3b76df1 --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ClientCodegenSettings.java @@ -0,0 +1,20 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators; + +import software.amazon.smithy.model.node.ObjectNode; +import software.amazon.smithy.model.shapes.ShapeId; + +public class ClientCodegenSettings { + private final ShapeId service; + + public ClientCodegenSettings(ObjectNode settings) { + this.service = ShapeId.from(settings.expectStringMember("service").getValue()); + } + + public ShapeId getService() { + return service; + } +} \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java index 9317bc0655a8..da9add080f13 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java @@ -2,15 +2,16 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -package com.amazonaws.util.awsclientsmithygenerator; +package com.amazonaws.util.awsclientsmithygenerator.generators; import java.util.function.Consumer; public class CppWriter { private final StringBuilder content = new StringBuilder(); - public void write(String text, Object... args) { + public CppWriter write(String text, Object... args) { content.append(String.format(text, args)).append("\n"); + return this; } public void openBlock(String opener, String closer, Consumer block) { diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriterDelegator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriterDelegator.java index d2adb93fdc2b..9d42e8b70900 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriterDelegator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriterDelegator.java @@ -2,7 +2,7 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -package com.amazonaws.util.awsclientsmithygenerator; +package com.amazonaws.util.awsclientsmithygenerator.generators; import software.amazon.smithy.build.FileManifest; import java.nio.file.Path; diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/HeaderCompilationParser.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/HeaderCompilationParser.java new file mode 100644 index 000000000000..6ca4a65f9264 --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/HeaderCompilationParser.java @@ -0,0 +1,65 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators; + +import software.amazon.smithy.build.PluginContext; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.*; +import software.amazon.smithy.aws.traits.ServiceTrait; +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; +import com.amazonaws.util.awsclientsmithygenerator.generators.templates.HeaderCompilationTemplate; +import com.amazonaws.util.awsclientsmithygenerator.generators.templates.HeaderCompilationCMakeTemplate; +import com.amazonaws.util.awsclientsmithygenerator.generators.ShapeUtil; +import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationData; +import java.util.*; + +public class HeaderCompilationParser { + private final PluginContext context; + private final ServiceShape service; + private final List paginatedOps; + private final CppWriterDelegator writerDelegator; + + public HeaderCompilationParser(PluginContext context, ServiceShape service, List paginatedOps) { + this.context = context; + this.service = service; + this.paginatedOps = paginatedOps; + this.writerDelegator = new CppWriterDelegator(context.getFileManifest()); + } + + public void run() { + List services = List.of(service); + generateSingleHeaderCompilationTest(services, paginatedOps); + writerDelegator.flushWriters(); + } + + private void generateSingleHeaderCompilationTest(List services, List allPaginatedOps) { + String serviceName = getServiceName(service); + String c2jServiceName = getC2jServiceName(service); + + // Generate single compilation test for all pagination headers in service's client-gen-tests + writerDelegator.useFileWriter( + "generated/tests/" + c2jServiceName + "-gen-tests/AllPaginationHeadersCompilationTest.cpp", + writer -> new HeaderCompilationTemplate(services, allPaginatedOps).render(writer) + ); + } + + + private String getServiceName(ServiceShape service) { + return service.getTrait(ServiceTrait.class) + .map(ServiceTrait::getSdkId) + .orElse(service.getId().getName()) + .replace(" ", "") + .replace("-", ""); + } + + private String getC2jServiceName(ServiceShape service) { + return service.getTrait(ServiceTrait.class) + .map(ServiceTrait::getSdkId) + .orElse(service.getId().getName()) + .trim() + .toLowerCase() + .replace(" ", "-"); + } +} \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java new file mode 100644 index 000000000000..9d4dd0e65043 --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.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; + +import software.amazon.smithy.build.PluginContext; +import software.amazon.smithy.build.SmithyBuildPlugin; +import software.amazon.smithy.model.knowledge.TopDownIndex; +import software.amazon.smithy.model.traits.PaginatedTrait; +import software.amazon.smithy.model.shapes.*; +import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationData; +import java.util.List; +import java.util.stream.Collectors; + +public class PaginationCodegenPlugin implements SmithyBuildPlugin { + + @Override + public String getName() { + return "cpp-codegen-pagination-plugin"; + } + + @Override + public void execute(PluginContext context) { + var model = context.getModel(); + + for (ServiceShape service : model.getServiceShapes()) { + // Find paginated operations using TopDownIndex + List paginatedOps = TopDownIndex.of(model).getContainedOperations(service).stream() + .filter(op -> op.hasTrait(PaginatedTrait.class)) + .map(op -> new PaginationData(op, op.expectTrait(PaginatedTrait.class), service)) + .collect(Collectors.toList()); + + if (!paginatedOps.isEmpty()) { + // Generate pagination files + PaginationParser parser = new PaginationParser(context, service, paginatedOps); + parser.run(); + + // Generate header compilation test + HeaderCompilationParser headerParser = new HeaderCompilationParser(context, service, paginatedOps); + headerParser.run(); + } + } + } +} diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationData.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationData.java similarity index 91% rename from tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationData.java rename to tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationData.java index d17d7718d865..62a13819dd1c 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationData.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationData.java @@ -2,7 +2,7 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -package com.amazonaws.util.awsclientsmithygenerator.generators; +package com.amazonaws.util.awsclientsmithygenerator.generators.templates; import software.amazon.smithy.model.shapes.*; import software.amazon.smithy.model.traits.PaginatedTrait; diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationHeaderWriter.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java similarity index 82% rename from tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationHeaderWriter.java rename to tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java index 09d91faa5965..08eb41cdc21b 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationHeaderWriter.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java @@ -9,6 +9,7 @@ import software.amazon.smithy.model.shapes.*; import software.amazon.smithy.model.traits.PaginatedTrait; import software.amazon.smithy.aws.traits.ServiceTrait; +import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationData; import java.nio.file.*; import java.util.*; @@ -73,8 +74,21 @@ private String generateTraitsHeader(PaginationData data, String serviceName) { sb.append(" return client.").append(opName).append("(request);\n }\n\n"); sb.append(" static bool HasMoreResults(const ResultType& result)\n {\n"); - // Check if there's a truncated field first, otherwise fall back to token check - sb.append(" return result.GetIsTruncated();\n"); + // Use the output token to determine if there are more results + if (trait.getOutputToken().isPresent()) { + String outToken = trait.getOutputToken().get(); + // Handle different token types - strings use .empty(), numbers check for non-zero + if (outToken.toLowerCase().contains("marker") || outToken.toLowerCase().contains("number")) { + // Numeric tokens - check if they exist/are set + sb.append(" return result.Get").append(capitalize(outToken)).append("() != 0;\n"); + } else { + // String tokens - check if not empty + sb.append(" return !result.Get").append(capitalize(outToken)).append("().empty();\n"); + } + } else { + // Fallback to checking for IsTruncated if no output token + sb.append(" return result.GetIsTruncated();\n"); + } sb.append(" }\n\n"); sb.append(" static void SetNextRequest(const ResultType& result, RequestType& request)\n {\n"); diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationParser.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java similarity index 83% rename from tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationParser.java rename to tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java index 45e9f7b58dc7..98c829628b74 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationParser.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java @@ -10,21 +10,25 @@ import software.amazon.smithy.model.node.ObjectNode; import software.amazon.smithy.model.shapes.*; import software.amazon.smithy.aws.traits.ServiceTrait; -import com.amazonaws.util.awsclientsmithygenerator.CppWriterDelegator; +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; +import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationData; +import com.amazonaws.util.awsclientsmithygenerator.generators.PaginationHeaderWriter; import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationClientTemplate; import java.util.*; public class PaginationParser { private final PluginContext context; private final Model model; - private final PaginationShapeDiscovery shapeDiscovery; + private final ServiceShape service; + private final List paginatedOps; private final CppWriterDelegator writerDelegator; private Map c2jMap; - public PaginationParser(PluginContext context) { + public PaginationParser(PluginContext context, ServiceShape service, List paginatedOps) { this.context = context; this.model = context.getModel(); - this.shapeDiscovery = new PaginationShapeDiscovery(model); + this.service = service; + this.paginatedOps = paginatedOps; this.writerDelegator = new CppWriterDelegator(context.getFileManifest()); // Initialize c2j map @@ -43,13 +47,7 @@ public PaginationParser(PluginContext context) { } public void run() { - for (ServiceShape service : model.getServiceShapes()) { - List paginatedOps = shapeDiscovery.findPaginatedOperations(service); - - if (!paginatedOps.isEmpty()) { - generatePaginationFiles(service, paginatedOps); - } - } + generatePaginationFiles(service, paginatedOps); writerDelegator.flushWriters(); } diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java new file mode 100644 index 000000000000..0745a619a92d --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java @@ -0,0 +1,25 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators; + +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.*; +import java.util.HashSet; +import java.util.Set; + +public class ShapeUtil { + + /** + * Returns all shapes referenced by a root shape, recursively. + */ + public static Set getReferences(Model model, Shape root) { + Set refs = new HashSet<>(); + refs.add(root); + for (var member : root.members()) { + refs.addAll(getReferences(model, model.expectShape(member.getTarget()))); + } + return refs; + } +} \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/HeaderCompilationCMakeTemplate.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/HeaderCompilationCMakeTemplate.java new file mode 100644 index 000000000000..598abe29a20b --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/HeaderCompilationCMakeTemplate.java @@ -0,0 +1,42 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.templates; + +import software.amazon.smithy.model.shapes.ServiceShape; +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; + +public class HeaderCompilationCMakeTemplate { + + public HeaderCompilationCMakeTemplate() { + } + + public void render(CppWriter writer) { + String testName = "all-pagination-headers-compilation-test"; + + writer.write("# Header compilation test for all pagination headers") + .write("cmake_minimum_required(VERSION 3.13)") + .write("") + .write("project($L)", testName) + .write("") + .write("find_package(aws-cpp-sdk-core REQUIRED)") + .write("find_package(GTest REQUIRED)") + .write("") + .write("add_executable($L", testName) + .write(" AllPaginationHeadersCompilationTest.cpp") + .write(")") + .write("") + .write("target_link_libraries($L", testName) + .write(" aws-cpp-sdk-core") + .write(" GTest::gtest") + .write(" GTest::gtest_main") + .write(")") + .write("") + .write("target_include_directories($L PRIVATE", testName) + .write(" ${CMAKE_CURRENT_SOURCE_DIR}") + .write(")") + .write("") + .write("add_test(NAME $L COMMAND $L)", testName, testName); + } +} \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/HeaderCompilationTemplate.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/HeaderCompilationTemplate.java new file mode 100644 index 000000000000..20e53fb6ff3a --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/HeaderCompilationTemplate.java @@ -0,0 +1,70 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.templates; + +import software.amazon.smithy.model.shapes.*; +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; +import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationData; +import java.util.*; + +public class HeaderCompilationTemplate { + private final List services; + private final List allPaginatedOps; + + public HeaderCompilationTemplate(List services, List allPaginatedOps) { + this.services = services; + this.allPaginatedOps = allPaginatedOps; + } + + public void render(CppWriter writer) { + writer.write("/**") + .write(" * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.") + .write(" * SPDX-License-Identifier: Apache-2.0.") + .write(" */") + .write("") + .write("// Header compilation test for ALL pagination headers") + .write("// This test ensures all generated pagination headers compile successfully") + .write(""); + + // Include all service headers + writeIncludes(writer); + + writer.write("") + .write("#include ") + .write("") + .write("class AllPaginationHeadersCompilationTest : public Aws::Testing::AwsCppSdkGTestSuite") + .write("{") + .write("};") + .write("") + .write("TEST_F(AllPaginationHeadersCompilationTest, AllPaginationHeadersCompile)") + .write("{") + .write(" // Test passes if compilation succeeds") + .write(" SUCCEED();") + .write("}"); + } + + private void writeIncludes(CppWriter writer) { + for (PaginationData paginationData : allPaginatedOps) { + ServiceShape service = paginationData.getService(); + String serviceName = getServiceName(service); + + // Include pagination client header + writer.writeInclude("aws/" + serviceName.toLowerCase() + "/" + serviceName + "ClientPagination.h"); + + // Include pagination traits headers + String operationName = paginationData.getOperation().getId().getName(); + writer.writeInclude("aws/" + serviceName.toLowerCase() + "/model/pagination/" + operationName + "PaginationTraits.h"); + } + } + + private String getServiceName(ServiceShape service) { + return service.getTrait(software.amazon.smithy.aws.traits.ServiceTrait.class) + .map(software.amazon.smithy.aws.traits.ServiceTrait::getSdkId) + .orElse(service.getId().getName()) + .replace(" ", "") + .replace("-", ""); + } + +} \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientTemplate.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientTemplate.java index 23ad0d4157c5..2338ec5aeec8 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientTemplate.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientTemplate.java @@ -4,8 +4,8 @@ */ package com.amazonaws.util.awsclientsmithygenerator.generators.templates; -import com.amazonaws.util.awsclientsmithygenerator.CppWriter; -import com.amazonaws.util.awsclientsmithygenerator.generators.PaginationData; +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; +import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationData; import software.amazon.smithy.model.shapes.ServiceShape; import software.amazon.smithy.aws.traits.ServiceTrait; import java.util.List; diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java deleted file mode 100644 index d28917359c15..000000000000 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -package com.amazonaws.util.awsclientsmithygenerator.generators; - -import software.amazon.smithy.build.PluginContext; -import software.amazon.smithy.build.SmithyBuildPlugin; - -public class PaginationCodegenPlugin implements SmithyBuildPlugin { - - @Override - public String getName() { - return "cpp-codegen-pagination-plugin"; - } - - @Override - public void execute(PluginContext context) { - PaginationParser parser = new PaginationParser(context); - parser.run(); - } -} diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationShapeDiscovery.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationShapeDiscovery.java deleted file mode 100644 index 14f5b67c143a..000000000000 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationShapeDiscovery.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -package com.amazonaws.util.awsclientsmithygenerator.generators; - -import software.amazon.smithy.model.Model; -import software.amazon.smithy.model.shapes.*; -import software.amazon.smithy.model.traits.PaginatedTrait; -import java.util.*; -import java.util.stream.Collectors; - -public class PaginationShapeDiscovery { - private final Model model; - - public PaginationShapeDiscovery(Model model) { - this.model = model; - } - - public List findPaginatedOperations(ServiceShape service) { - return service.getOperations().stream() - .map(id -> model.expectShape(id, OperationShape.class)) - .filter(op -> op.hasTrait(PaginatedTrait.class)) - .map(op -> new PaginationData(op, op.expectTrait(PaginatedTrait.class), service)) - .collect(Collectors.toList()); - } - - public Set getReferencedStructures(List paginatedOps) { - Set structures = new HashSet<>(); - for (PaginationData data : paginatedOps) { - OperationShape op = data.getOperation(); - structures.add(model.expectShape(op.getInputShape(), StructureShape.class)); - structures.add(model.expectShape(op.getOutputShape(), StructureShape.class)); - } - return structures; - } -} \ No newline at end of file diff --git a/tools/scripts/codegen/pagination_gen.py b/tools/scripts/codegen/pagination_gen.py index 1a5b7704ee26..5a70e7319714 100644 --- a/tools/scripts/codegen/pagination_gen.py +++ b/tools/scripts/codegen/pagination_gen.py @@ -88,11 +88,24 @@ def _copy_cpp_codegen_contents(self, top_level_dir: str, plugin_name: str, targe for item in os.listdir(source_dir): source_item = os.path.join(source_dir, item) + + # Handle test directories separately - move to generated/tests + if item == "generated" and os.path.isdir(source_item): + generated_source = os.path.join(source_item, "tests") + if os.path.exists(generated_source): + test_target_dir = os.path.abspath("generated/tests") + os.makedirs(test_target_dir, exist_ok=True) + shutil.copytree(generated_source, test_target_dir, dirs_exist_ok=True) + if self.debug: + print(f"Copied tests from '{generated_source}' to '{test_target_dir}'") + continue + target_item = os.path.join(service_target_dir, item) if os.path.isdir(source_item): shutil.copytree(source_item, target_item, dirs_exist_ok=True) else: shutil.copy2(source_item, target_item) + if self.debug: print(f"Copied from '{source_dir}' to '{service_target_dir}'") From 7e0011679e4fe5adc74ff02f7d1c3084b3520c62 Mon Sep 17 00:00:00 2001 From: kai lin Date: Thu, 15 Jan 2026 15:32:38 -0500 Subject: [PATCH 07/46] updated cppwriter to use smithy library --- ...t.cpp => S3PaginationCompilationTests.cpp} | 10 ++--- .../generators/CppImportContainer.java | 36 ++++++++++++++++ .../generators/CppWriter.java | 43 ++++++++++--------- ...PaginationData.java => OperationData.java} | 12 +++--- .../generators/PaginationCodegenPlugin.java | 10 +++-- ...a => PaginationCompilationTestParser.java} | 20 ++++----- .../generators/PaginationHeaderWriter.java | 11 ++--- .../generators/PaginationParser.java | 9 ++-- .../HeaderCompilationCMakeTemplate.java | 42 ------------------ .../templates/PaginationClientTemplate.java | 13 +++--- ...> PaginationCompilationTestGenerator.java} | 37 +++++++++------- .../codegen/cpp-pagination/smithy-build.json | 12 +++++- 12 files changed, 135 insertions(+), 120 deletions(-) rename generated/tests/s3-gen-tests/{AllPaginationHeadersCompilationTest.cpp => S3PaginationCompilationTests.cpp} (71%) create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppImportContainer.java rename tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/{PaginationData.java => OperationData.java} (60%) rename tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/{HeaderCompilationParser.java => PaginationCompilationTestParser.java} (70%) delete mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/HeaderCompilationCMakeTemplate.java rename tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/{HeaderCompilationTemplate.java => PaginationCompilationTestGenerator.java} (63%) diff --git a/generated/tests/s3-gen-tests/AllPaginationHeadersCompilationTest.cpp b/generated/tests/s3-gen-tests/S3PaginationCompilationTests.cpp similarity index 71% rename from generated/tests/s3-gen-tests/AllPaginationHeadersCompilationTest.cpp rename to generated/tests/s3-gen-tests/S3PaginationCompilationTests.cpp index 418f96be4ce8..0fa4ac48c381 100644 --- a/generated/tests/s3-gen-tests/AllPaginationHeadersCompilationTest.cpp +++ b/generated/tests/s3-gen-tests/S3PaginationCompilationTests.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0. */ -// Header compilation test for ALL pagination headers +// Header compilation test for S3 pagination headers // This test ensures all generated pagination headers compile successfully #include @@ -17,12 +17,12 @@ #include -class AllPaginationHeadersCompilationTest : public Aws::Testing::AwsCppSdkGTestSuite +class S3PaginationCompilationTest : public Aws::Testing::AwsCppSdkGTestSuite { }; -TEST_F(AllPaginationHeadersCompilationTest, AllPaginationHeadersCompile) +TEST_F(S3PaginationCompilationTest, S3PaginationHeadersCompile) { - // Test passes if compilation succeeds - SUCCEED(); + // Test passes if compilation succeeds + SUCCEED(); } diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppImportContainer.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppImportContainer.java new file mode 100644 index 000000000000..8c26688ae5f0 --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppImportContainer.java @@ -0,0 +1,36 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators; + +import software.amazon.smithy.codegen.core.ImportContainer; +import software.amazon.smithy.codegen.core.Symbol; +import java.util.HashSet; +import java.util.Set; + +/** + * CppImportContainer tracks symbols used in code generation. + * For C++, we handle includes manually via writeInclude method. + */ +public class CppImportContainer implements ImportContainer { + private final Set imports = new HashSet<>(); + + @Override + public void importSymbol(Symbol symbol, String alias) { + // Track the symbol's namespace for potential future use + if (symbol.getNamespace() != null && !symbol.getNamespace().isEmpty()) { + imports.add(symbol.getNamespace()); + } + } + + public Set getImports() { + return imports; + } + + @Override + public String toString() { + // Return empty string since we handle includes manually + return ""; + } +} \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java index da9add080f13..950e772d7939 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java @@ -4,36 +4,39 @@ */ package com.amazonaws.util.awsclientsmithygenerator.generators; -import java.util.function.Consumer; +import software.amazon.smithy.codegen.core.SymbolWriter; -public class CppWriter { - private final StringBuilder content = new StringBuilder(); +public class CppWriter extends SymbolWriter { - public CppWriter write(String text, Object... args) { - content.append(String.format(text, args)).append("\n"); - return this; - } - - public void openBlock(String opener, String closer, Consumer block) { - write(opener); - block.accept(null); - write(closer); + public CppWriter() { + super(new CppImportContainer()); + + // Add custom formatter for symbols + putFormatter('T', (arg, indent) -> { + if (!(arg instanceof software.amazon.smithy.codegen.core.Symbol symbol)) { + throw new software.amazon.smithy.codegen.core.CodegenException("Expected a symbol but got " + arg); + } + + // Record our symbol so we can generate appropriate includes later if needed + getImportContainer().importSymbol(symbol, null); + + // For C++, use namespace::name syntax (e.g. Aws::S3::Model::ListBucketsRequest) + if (symbol.getNamespace() != null && !symbol.getNamespace().isEmpty()) { + return symbol.getNamespace() + "::" + symbol.getName(); + } + return symbol.getName(); + }); } public void writeInclude(String header) { - write("#include <%s>", header); + write("#include <$L>", header); } public void writeNamespaceOpen(String namespace) { - write("namespace %s\n{", namespace); + write("namespace $L\n{", namespace); } public void writeNamespaceClose(String namespace) { - write("} // namespace %s", namespace); - } - - @Override - public String toString() { - return content.toString(); + write("} // namespace $L", namespace); } } \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationData.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/OperationData.java similarity index 60% rename from tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationData.java rename to tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/OperationData.java index 62a13819dd1c..7d4c3bec8897 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationData.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/OperationData.java @@ -2,17 +2,17 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -package com.amazonaws.util.awsclientsmithygenerator.generators.templates; +package com.amazonaws.util.awsclientsmithygenerator.generators; import software.amazon.smithy.model.shapes.*; -import software.amazon.smithy.model.traits.PaginatedTrait; +import software.amazon.smithy.model.traits.Trait; -public class PaginationData { +public class OperationData { private final OperationShape operation; - private final PaginatedTrait trait; + private final T trait; private final ServiceShape service; - public PaginationData(OperationShape operation, PaginatedTrait trait, ServiceShape service) { + public OperationData(OperationShape operation, T trait, ServiceShape service) { this.operation = operation; this.trait = trait; this.service = service; @@ -22,7 +22,7 @@ public OperationShape getOperation() { return operation; } - public PaginatedTrait getTrait() { + public T getTrait() { return trait; } diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java index 9d4dd0e65043..9a8cb71c83eb 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java @@ -9,7 +9,9 @@ import software.amazon.smithy.model.knowledge.TopDownIndex; import software.amazon.smithy.model.traits.PaginatedTrait; import software.amazon.smithy.model.shapes.*; -import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationData; +import com.amazonaws.util.awsclientsmithygenerator.generators.OperationData; +import software.amazon.smithy.model.traits.PaginatedTrait; +import com.amazonaws.util.awsclientsmithygenerator.generators.PaginationCompilationTestParser; import java.util.List; import java.util.stream.Collectors; @@ -26,9 +28,9 @@ public void execute(PluginContext context) { for (ServiceShape service : model.getServiceShapes()) { // Find paginated operations using TopDownIndex - List paginatedOps = TopDownIndex.of(model).getContainedOperations(service).stream() + List> paginatedOps = TopDownIndex.of(model).getContainedOperations(service).stream() .filter(op -> op.hasTrait(PaginatedTrait.class)) - .map(op -> new PaginationData(op, op.expectTrait(PaginatedTrait.class), service)) + .map(op -> new OperationData<>(op, op.expectTrait(PaginatedTrait.class), service)) .collect(Collectors.toList()); if (!paginatedOps.isEmpty()) { @@ -37,7 +39,7 @@ public void execute(PluginContext context) { parser.run(); // Generate header compilation test - HeaderCompilationParser headerParser = new HeaderCompilationParser(context, service, paginatedOps); + PaginationCompilationTestParser headerParser = new PaginationCompilationTestParser(context, service, paginatedOps); headerParser.run(); } } diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/HeaderCompilationParser.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCompilationTestParser.java similarity index 70% rename from tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/HeaderCompilationParser.java rename to tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCompilationTestParser.java index 6ca4a65f9264..146964ac3a31 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/HeaderCompilationParser.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCompilationTestParser.java @@ -5,23 +5,21 @@ package com.amazonaws.util.awsclientsmithygenerator.generators; import software.amazon.smithy.build.PluginContext; -import software.amazon.smithy.model.Model; import software.amazon.smithy.model.shapes.*; import software.amazon.smithy.aws.traits.ServiceTrait; import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; -import com.amazonaws.util.awsclientsmithygenerator.generators.templates.HeaderCompilationTemplate; -import com.amazonaws.util.awsclientsmithygenerator.generators.templates.HeaderCompilationCMakeTemplate; -import com.amazonaws.util.awsclientsmithygenerator.generators.ShapeUtil; -import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationData; +import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationCompilationTestGenerator; +import com.amazonaws.util.awsclientsmithygenerator.generators.OperationData; +import software.amazon.smithy.model.traits.PaginatedTrait; import java.util.*; -public class HeaderCompilationParser { +public class PaginationCompilationTestParser { private final PluginContext context; private final ServiceShape service; - private final List paginatedOps; + private final List> paginatedOps; private final CppWriterDelegator writerDelegator; - public HeaderCompilationParser(PluginContext context, ServiceShape service, List paginatedOps) { + public PaginationCompilationTestParser(PluginContext context, ServiceShape service, List> paginatedOps) { this.context = context; this.service = service; this.paginatedOps = paginatedOps; @@ -34,14 +32,14 @@ public void run() { writerDelegator.flushWriters(); } - private void generateSingleHeaderCompilationTest(List services, List allPaginatedOps) { + private void generateSingleHeaderCompilationTest(List services, List> allPaginatedOps) { String serviceName = getServiceName(service); String c2jServiceName = getC2jServiceName(service); // Generate single compilation test for all pagination headers in service's client-gen-tests writerDelegator.useFileWriter( - "generated/tests/" + c2jServiceName + "-gen-tests/AllPaginationHeadersCompilationTest.cpp", - writer -> new HeaderCompilationTemplate(services, allPaginatedOps).render(writer) + "generated/tests/" + c2jServiceName + "-gen-tests/" + serviceName + "PaginationCompilationTests.cpp", + writer -> new PaginationCompilationTestGenerator(services, allPaginatedOps).render(writer) ); } diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java index 08eb41cdc21b..c1c67d9ee06f 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java @@ -9,17 +9,18 @@ import software.amazon.smithy.model.shapes.*; import software.amazon.smithy.model.traits.PaginatedTrait; import software.amazon.smithy.aws.traits.ServiceTrait; -import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationData; +import com.amazonaws.util.awsclientsmithygenerator.generators.OperationData; +import software.amazon.smithy.model.traits.PaginatedTrait; import java.nio.file.*; import java.util.*; public class PaginationHeaderWriter { private final PluginContext context; private final ServiceShape service; - private final List paginatedOps; + private final List> paginatedOps; private final String c2jServiceName; - public PaginationHeaderWriter(PluginContext context, ServiceShape service, List paginatedOps, String c2jServiceName) { + public PaginationHeaderWriter(PluginContext context, ServiceShape service, List> paginatedOps, String c2jServiceName) { this.context = context; this.service = service; this.paginatedOps = paginatedOps; @@ -35,7 +36,7 @@ public void write() { Path outputPath = context.getFileManifest().getBaseDir() .resolve("include/aws/" + c2jServiceName + "/model/pagination"); - for (PaginationData data : paginatedOps) { + for (OperationData data : paginatedOps) { String content = generateTraitsHeader(data, serviceName); String fileName = data.getOperation().getId().getName() + "PaginationTraits.h"; @@ -48,7 +49,7 @@ public void write() { } } - private String generateTraitsHeader(PaginationData data, String serviceName) { + private String generateTraitsHeader(OperationData data, String serviceName) { OperationShape op = data.getOperation(); PaginatedTrait trait = data.getTrait(); String opName = op.getId().getName(); diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java index 98c829628b74..389e2a6669ec 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java @@ -11,7 +11,8 @@ import software.amazon.smithy.model.shapes.*; import software.amazon.smithy.aws.traits.ServiceTrait; import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; -import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationData; +import com.amazonaws.util.awsclientsmithygenerator.generators.OperationData; +import software.amazon.smithy.model.traits.PaginatedTrait; import com.amazonaws.util.awsclientsmithygenerator.generators.PaginationHeaderWriter; import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationClientTemplate; import java.util.*; @@ -20,11 +21,11 @@ public class PaginationParser { private final PluginContext context; private final Model model; private final ServiceShape service; - private final List paginatedOps; + private final List> paginatedOps; private final CppWriterDelegator writerDelegator; private Map c2jMap; - public PaginationParser(PluginContext context, ServiceShape service, List paginatedOps) { + public PaginationParser(PluginContext context, ServiceShape service, List> paginatedOps) { this.context = context; this.model = context.getModel(); this.service = service; @@ -51,7 +52,7 @@ public void run() { writerDelegator.flushWriters(); } - private void generatePaginationFiles(ServiceShape service, List paginatedOps) { + private void generatePaginationFiles(ServiceShape service, List> paginatedOps) { String serviceName = getServiceName(service); String c2jServiceName = getC2jServiceName(service); diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/HeaderCompilationCMakeTemplate.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/HeaderCompilationCMakeTemplate.java deleted file mode 100644 index 598abe29a20b..000000000000 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/HeaderCompilationCMakeTemplate.java +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -package com.amazonaws.util.awsclientsmithygenerator.generators.templates; - -import software.amazon.smithy.model.shapes.ServiceShape; -import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; - -public class HeaderCompilationCMakeTemplate { - - public HeaderCompilationCMakeTemplate() { - } - - public void render(CppWriter writer) { - String testName = "all-pagination-headers-compilation-test"; - - writer.write("# Header compilation test for all pagination headers") - .write("cmake_minimum_required(VERSION 3.13)") - .write("") - .write("project($L)", testName) - .write("") - .write("find_package(aws-cpp-sdk-core REQUIRED)") - .write("find_package(GTest REQUIRED)") - .write("") - .write("add_executable($L", testName) - .write(" AllPaginationHeadersCompilationTest.cpp") - .write(")") - .write("") - .write("target_link_libraries($L", testName) - .write(" aws-cpp-sdk-core") - .write(" GTest::gtest") - .write(" GTest::gtest_main") - .write(")") - .write("") - .write("target_include_directories($L PRIVATE", testName) - .write(" ${CMAKE_CURRENT_SOURCE_DIR}") - .write(")") - .write("") - .write("add_test(NAME $L COMMAND $L)", testName, testName); - } -} \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientTemplate.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientTemplate.java index 2338ec5aeec8..4b4d41e85b61 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientTemplate.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientTemplate.java @@ -5,16 +5,17 @@ package com.amazonaws.util.awsclientsmithygenerator.generators.templates; import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; -import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationData; +import com.amazonaws.util.awsclientsmithygenerator.generators.OperationData; import software.amazon.smithy.model.shapes.ServiceShape; import software.amazon.smithy.aws.traits.ServiceTrait; +import software.amazon.smithy.model.traits.PaginatedTrait; import java.util.List; public class PaginationClientTemplate { private final ServiceShape service; - private final List paginatedOps; + private final List> paginatedOps; - public PaginationClientTemplate(ServiceShape service, List paginatedOps) { + public PaginationClientTemplate(ServiceShape service, List> paginatedOps) { this.service = service; this.paginatedOps = paginatedOps; } @@ -38,7 +39,7 @@ private void renderIncludes(CppWriter writer, String serviceName) { writer.writeInclude("aws/" + serviceName.toLowerCase() + "/" + serviceName + "Client.h"); writer.writeInclude("aws/core/utils/pagination/Paginator.h"); - for (PaginationData data : paginatedOps) { + for (OperationData data : paginatedOps) { String opName = data.getOperation().getId().getName(); writer.writeInclude("aws/" + serviceName.toLowerCase() + "/model/pagination/" + opName + "PaginationTraits.h"); } @@ -50,9 +51,9 @@ private void renderNamespaces(CppWriter writer, String serviceName) { writer.writeNamespaceOpen(serviceName); writer.write(""); - for (PaginationData data : paginatedOps) { + for (OperationData data : paginatedOps) { String opName = data.getOperation().getId().getName(); - writer.write("using %sPaginator = Aws::Utils::Pagination::PagePaginator<%sClient, Model::%sRequest, Pagination::%sPaginationTraits>;", + writer.write("using $LPaginator = Aws::Utils::Pagination::PagePaginator<$LClient, Model::$LRequest, Pagination::$LPaginationTraits>;", opName, serviceName, opName, opName); } diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/HeaderCompilationTemplate.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java similarity index 63% rename from tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/HeaderCompilationTemplate.java rename to tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java index 20e53fb6ff3a..4e86c8a6fc27 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/HeaderCompilationTemplate.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java @@ -6,25 +6,28 @@ import software.amazon.smithy.model.shapes.*; import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; -import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationData; +import com.amazonaws.util.awsclientsmithygenerator.generators.OperationData; +import software.amazon.smithy.model.traits.PaginatedTrait; import java.util.*; -public class HeaderCompilationTemplate { +public class PaginationCompilationTestGenerator { private final List services; - private final List allPaginatedOps; + private final List> allPaginatedOps; - public HeaderCompilationTemplate(List services, List allPaginatedOps) { + public PaginationCompilationTestGenerator(List services, List> allPaginatedOps) { this.services = services; this.allPaginatedOps = allPaginatedOps; } public void render(CppWriter writer) { + String serviceName = getServiceName(services.get(0)); + writer.write("/**") .write(" * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.") .write(" * SPDX-License-Identifier: Apache-2.0.") .write(" */") .write("") - .write("// Header compilation test for ALL pagination headers") + .write("// Header compilation test for " + serviceName + " pagination headers") .write("// This test ensures all generated pagination headers compile successfully") .write(""); @@ -33,20 +36,22 @@ public void render(CppWriter writer) { writer.write("") .write("#include ") - .write("") - .write("class AllPaginationHeadersCompilationTest : public Aws::Testing::AwsCppSdkGTestSuite") - .write("{") - .write("};") - .write("") - .write("TEST_F(AllPaginationHeadersCompilationTest, AllPaginationHeadersCompile)") - .write("{") - .write(" // Test passes if compilation succeeds") - .write(" SUCCEED();") - .write("}"); + .write(""); + + writer.openBlock("class " + serviceName + "PaginationCompilationTest : public Aws::Testing::AwsCppSdkGTestSuite\n{", "};", () -> { + // Empty class body + }); + + writer.write(""); + + writer.openBlock("TEST_F(" + serviceName + "PaginationCompilationTest, " + serviceName + "PaginationHeadersCompile)\n{", "}", () -> { + writer.write(" // Test passes if compilation succeeds") + .write(" SUCCEED();"); + }); } private void writeIncludes(CppWriter writer) { - for (PaginationData paginationData : allPaginatedOps) { + for (OperationData paginationData : allPaginatedOps) { ServiceShape service = paginationData.getService(); String serviceName = getServiceName(service); diff --git a/tools/code-generation/smithy/codegen/cpp-pagination/smithy-build.json b/tools/code-generation/smithy/codegen/cpp-pagination/smithy-build.json index a3adf6fee9d5..40328dc60a77 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination/smithy-build.json +++ b/tools/code-generation/smithy/codegen/cpp-pagination/smithy-build.json @@ -7,7 +7,17 @@ ], "plugins": { "cpp-codegen-pagination-plugin": { - "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service \": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" + "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" + } + } + }, + "dynamodb.2012-08-10": { + "imports": [ + "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/dynamodb.json" + ], + "plugins": { + "cpp-codegen-pagination-plugin": { + "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" } } } From 9678fe0326a0248c219e4890d07d63d7f615aa9b Mon Sep 17 00:00:00 2001 From: kai lin Date: Thu, 15 Jan 2026 16:02:07 -0500 Subject: [PATCH 08/46] changed parsers to be more generic --- ...Parser.java => CompilationTestParser.java} | 30 ++--- .../generators/CppWriter.java | 9 +- ...ginationParser.java => FeatureParser.java} | 42 +++--- .../generators/PaginationCodegenPlugin.java | 30 ++++- .../generators/PaginationHeaderWriter.java | 114 ---------------- ...a => PaginationClientHeaderGenerator.java} | 4 +- .../PaginationCompilationTestGenerator.java | 23 +++- .../templates/PaginationTraitsGenerator.java | 127 ++++++++++++++++++ 8 files changed, 215 insertions(+), 164 deletions(-) rename tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/{PaginationCompilationTestParser.java => CompilationTestParser.java} (59%) rename tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/{PaginationParser.java => FeatureParser.java} (63%) delete mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java rename tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/{PaginationClientTemplate.java => PaginationClientHeaderGenerator.java} (94%) create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCompilationTestParser.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CompilationTestParser.java similarity index 59% rename from tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCompilationTestParser.java rename to tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CompilationTestParser.java index 146964ac3a31..4d7e1c5821c5 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCompilationTestParser.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CompilationTestParser.java @@ -7,42 +7,42 @@ import software.amazon.smithy.build.PluginContext; import software.amazon.smithy.model.shapes.*; import software.amazon.smithy.aws.traits.ServiceTrait; -import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; -import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationCompilationTestGenerator; -import com.amazonaws.util.awsclientsmithygenerator.generators.OperationData; -import software.amazon.smithy.model.traits.PaginatedTrait; +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; import java.util.*; +import java.util.function.Consumer; -public class PaginationCompilationTestParser { +public class CompilationTestParser { private final PluginContext context; private final ServiceShape service; - private final List> paginatedOps; + private final List operations; private final CppWriterDelegator writerDelegator; + private final String testType; + private final Consumer renderFunction; - public PaginationCompilationTestParser(PluginContext context, ServiceShape service, List> paginatedOps) { + public CompilationTestParser(PluginContext context, ServiceShape service, List operations, + String testType, Consumer renderFunction) { this.context = context; this.service = service; - this.paginatedOps = paginatedOps; + this.operations = operations; this.writerDelegator = new CppWriterDelegator(context.getFileManifest()); + this.testType = testType; + this.renderFunction = renderFunction; } public void run() { - List services = List.of(service); - generateSingleHeaderCompilationTest(services, paginatedOps); + generateCompilationTest(); writerDelegator.flushWriters(); } - private void generateSingleHeaderCompilationTest(List services, List> allPaginatedOps) { + private void generateCompilationTest() { String serviceName = getServiceName(service); String c2jServiceName = getC2jServiceName(service); - // Generate single compilation test for all pagination headers in service's client-gen-tests writerDelegator.useFileWriter( - "generated/tests/" + c2jServiceName + "-gen-tests/" + serviceName + "PaginationCompilationTests.cpp", - writer -> new PaginationCompilationTestGenerator(services, allPaginatedOps).render(writer) + "generated/tests/" + c2jServiceName + "-gen-tests/" + serviceName + testType + "CompilationTests.cpp", + renderFunction ); } - private String getServiceName(ServiceShape service) { return service.getTrait(ServiceTrait.class) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java index 950e772d7939..bf1ad4ffc53b 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java @@ -28,15 +28,18 @@ public CppWriter() { }); } - public void writeInclude(String header) { + public CppWriter writeInclude(String header) { write("#include <$L>", header); + return this; } - public void writeNamespaceOpen(String namespace) { + public CppWriter writeNamespaceOpen(String namespace) { write("namespace $L\n{", namespace); + return this; } - public void writeNamespaceClose(String namespace) { + public CppWriter writeNamespaceClose(String namespace) { write("} // namespace $L", namespace); + return this; } } \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/FeatureParser.java similarity index 63% rename from tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java rename to tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/FeatureParser.java index 389e2a6669ec..53d2938e2457 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationParser.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/FeatureParser.java @@ -10,26 +10,24 @@ import software.amazon.smithy.model.node.ObjectNode; import software.amazon.smithy.model.shapes.*; import software.amazon.smithy.aws.traits.ServiceTrait; -import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; -import com.amazonaws.util.awsclientsmithygenerator.generators.OperationData; -import software.amazon.smithy.model.traits.PaginatedTrait; -import com.amazonaws.util.awsclientsmithygenerator.generators.PaginationHeaderWriter; -import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationClientTemplate; import java.util.*; +import java.util.function.Consumer; -public class PaginationParser { +public class FeatureParser { private final PluginContext context; private final Model model; private final ServiceShape service; - private final List> paginatedOps; + private final List operations; private final CppWriterDelegator writerDelegator; - private Map c2jMap; + private final Map c2jMap; + private final String featureName; - public PaginationParser(PluginContext context, ServiceShape service, List> paginatedOps) { + public FeatureParser(PluginContext context, ServiceShape service, List operations, String featureName) { this.context = context; this.model = context.getModel(); this.service = service; - this.paginatedOps = paginatedOps; + this.operations = operations; + this.featureName = featureName; this.writerDelegator = new CppWriterDelegator(context.getFileManifest()); // Initialize c2j map @@ -47,26 +45,28 @@ public PaginationParser(PluginContext context, ServiceShape service, List> generationLogic) { + generationLogic.accept(this); writerDelegator.flushWriters(); } - private void generatePaginationFiles(ServiceShape service, List> paginatedOps) { + public void generateClientHeader(String fileName, Consumer generator) { String serviceName = getServiceName(service); String c2jServiceName = getC2jServiceName(service); - // Generate client pagination header writerDelegator.useFileWriter( - "include/aws/" + c2jServiceName + "/" + serviceName + "ClientPagination.h", - writer -> new PaginationClientTemplate(service, paginatedOps).render(writer) + "include/aws/" + c2jServiceName + "/" + fileName, + generator ); - - // Generate pagination traits headers - PaginationHeaderWriter headerWriter = new PaginationHeaderWriter(context, service, paginatedOps, c2jServiceName); - headerWriter.write(); } + public PluginContext getContext() { return context; } + public ServiceShape getService() { return service; } + public List getOperations() { return operations; } + public String getFeatureName() { return featureName; } + public String getServiceName() { return getServiceName(service); } + public String getC2jServiceName() { return getC2jServiceName(service); } + private String getServiceName(ServiceShape service) { return service.getTrait(ServiceTrait.class) .map(ServiceTrait::getSdkId) @@ -85,4 +85,4 @@ private String getC2jServiceName(ServiceShape service) { return c2jMap.getOrDefault(sdkId, sdkId); } -} +} \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java index 9a8cb71c83eb..1681570a7a7d 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java @@ -10,8 +10,11 @@ import software.amazon.smithy.model.traits.PaginatedTrait; import software.amazon.smithy.model.shapes.*; import com.amazonaws.util.awsclientsmithygenerator.generators.OperationData; +import com.amazonaws.util.awsclientsmithygenerator.generators.FeatureParser; +import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationTraitsGenerator; +import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationClientHeaderGenerator; +import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationCompilationTestGenerator; import software.amazon.smithy.model.traits.PaginatedTrait; -import com.amazonaws.util.awsclientsmithygenerator.generators.PaginationCompilationTestParser; import java.util.List; import java.util.stream.Collectors; @@ -35,12 +38,29 @@ public void execute(PluginContext context) { if (!paginatedOps.isEmpty()) { // Generate pagination files - PaginationParser parser = new PaginationParser(context, service, paginatedOps); - parser.run(); + FeatureParser> parser = new FeatureParser<>(context, service, paginatedOps, "Pagination"); + parser.run(featureParser -> { + String serviceName = featureParser.getServiceName(); + + // Generate client pagination header + featureParser.generateClientHeader( + serviceName + "ClientPagination.h", + writer -> new PaginationClientHeaderGenerator(featureParser.getService(), featureParser.getOperations()).render(writer) + ); + + // Generate pagination traits headers + PaginationTraitsGenerator headerWriter = new PaginationTraitsGenerator( + featureParser.getContext(), + featureParser.getService(), + featureParser.getOperations(), + featureParser.getC2jServiceName() + ); + headerWriter.write(); + }); // Generate header compilation test - PaginationCompilationTestParser headerParser = new PaginationCompilationTestParser(context, service, paginatedOps); - headerParser.run(); + PaginationCompilationTestGenerator headerGenerator = new PaginationCompilationTestGenerator(context, service, paginatedOps); + headerGenerator.run(); } } } diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java deleted file mode 100644 index c1c67d9ee06f..000000000000 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationHeaderWriter.java +++ /dev/null @@ -1,114 +0,0 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -package com.amazonaws.util.awsclientsmithygenerator.generators; - -import software.amazon.smithy.build.PluginContext; -import software.amazon.smithy.codegen.core.SymbolProvider; -import software.amazon.smithy.model.shapes.*; -import software.amazon.smithy.model.traits.PaginatedTrait; -import software.amazon.smithy.aws.traits.ServiceTrait; -import com.amazonaws.util.awsclientsmithygenerator.generators.OperationData; -import software.amazon.smithy.model.traits.PaginatedTrait; -import java.nio.file.*; -import java.util.*; - -public class PaginationHeaderWriter { - private final PluginContext context; - private final ServiceShape service; - private final List> paginatedOps; - private final String c2jServiceName; - - public PaginationHeaderWriter(PluginContext context, ServiceShape service, List> paginatedOps, String c2jServiceName) { - this.context = context; - this.service = service; - this.paginatedOps = paginatedOps; - this.c2jServiceName = c2jServiceName; - } - - public void write() { - String serviceName = service.getTrait(ServiceTrait.class) - .map(ServiceTrait::getSdkId) - .orElse(service.getId().getName()) - .replace(" ", "") - .replace("-", ""); - Path outputPath = context.getFileManifest().getBaseDir() - .resolve("include/aws/" + c2jServiceName + "/model/pagination"); - - for (OperationData data : paginatedOps) { - String content = generateTraitsHeader(data, serviceName); - String fileName = data.getOperation().getId().getName() + "PaginationTraits.h"; - - try { - Files.createDirectories(outputPath); - Files.writeString(outputPath.resolve(fileName), content); - } catch (Exception e) { - throw new RuntimeException("Failed to write pagination traits header", e); - } - } - } - - private String generateTraitsHeader(OperationData data, String serviceName) { - OperationShape op = data.getOperation(); - PaginatedTrait trait = data.getTrait(); - String opName = op.getId().getName(); - - StringBuilder sb = new StringBuilder(); - sb.append("/**\n"); - sb.append(" * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n"); - sb.append(" * SPDX-License-Identifier: Apache-2.0.\n"); - sb.append(" */\n\n"); - sb.append("#pragma once\n"); - sb.append("#include \n"); - sb.append("#include \n"); - sb.append("#include \n"); - sb.append("#include \n\n"); - sb.append("namespace Aws\n{\nnamespace ").append(serviceName).append("\n{\nnamespace Pagination\n{\n\n"); - sb.append("struct ").append(opName).append("PaginationTraits\n{\n"); - sb.append(" using RequestType = Model::").append(opName).append("Request;\n"); - sb.append(" using ResultType = Model::").append(opName).append("Result;\n"); - sb.append(" using OutcomeType = Model::").append(opName).append("Outcome;\n"); - sb.append(" using ClientType = ").append(serviceName).append("Client;\n\n"); - - sb.append(" static OutcomeType Invoke(ClientType& client, const RequestType& request)\n {\n"); - sb.append(" return client.").append(opName).append("(request);\n }\n\n"); - - sb.append(" static bool HasMoreResults(const ResultType& result)\n {\n"); - // Use the output token to determine if there are more results - if (trait.getOutputToken().isPresent()) { - String outToken = trait.getOutputToken().get(); - // Handle different token types - strings use .empty(), numbers check for non-zero - if (outToken.toLowerCase().contains("marker") || outToken.toLowerCase().contains("number")) { - // Numeric tokens - check if they exist/are set - sb.append(" return result.Get").append(capitalize(outToken)).append("() != 0;\n"); - } else { - // String tokens - check if not empty - sb.append(" return !result.Get").append(capitalize(outToken)).append("().empty();\n"); - } - } else { - // Fallback to checking for IsTruncated if no output token - sb.append(" return result.GetIsTruncated();\n"); - } - sb.append(" }\n\n"); - - sb.append(" static void SetNextRequest(const ResultType& result, RequestType& request)\n {\n"); - if (trait.getInputToken().isPresent() && trait.getOutputToken().isPresent()) { - String inToken = trait.getInputToken().get(); - String outToken = trait.getOutputToken().get(); - sb.append(" request.Set").append(capitalize(inToken)).append("(result.Get").append(capitalize(outToken)).append("());\n"); - } - sb.append(" }\n"); - - sb.append("};\n\n"); - sb.append("} // namespace Pagination\n"); - sb.append("} // namespace ").append(serviceName).append("\n"); - sb.append("} // namespace Aws\n"); - - return sb.toString(); - } - - private String capitalize(String str) { - return str.substring(0, 1).toUpperCase() + str.substring(1); - } -} diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientTemplate.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java similarity index 94% rename from tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientTemplate.java rename to tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java index 4b4d41e85b61..ff00f56872f6 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientTemplate.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java @@ -11,11 +11,11 @@ import software.amazon.smithy.model.traits.PaginatedTrait; import java.util.List; -public class PaginationClientTemplate { +public class PaginationClientHeaderGenerator { private final ServiceShape service; private final List> paginatedOps; - public PaginationClientTemplate(ServiceShape service, List> paginatedOps) { + public PaginationClientHeaderGenerator(ServiceShape service, List> paginatedOps) { this.service = service; this.paginatedOps = paginatedOps; } diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java index 4e86c8a6fc27..155d2bcdac2c 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java @@ -4,23 +4,37 @@ */ package com.amazonaws.util.awsclientsmithygenerator.generators.templates; +import software.amazon.smithy.build.PluginContext; import software.amazon.smithy.model.shapes.*; import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; +import com.amazonaws.util.awsclientsmithygenerator.generators.CompilationTestParser; import com.amazonaws.util.awsclientsmithygenerator.generators.OperationData; import software.amazon.smithy.model.traits.PaginatedTrait; import java.util.*; public class PaginationCompilationTestGenerator { - private final List services; + private final CompilationTestParser> parser; private final List> allPaginatedOps; - public PaginationCompilationTestGenerator(List services, List> allPaginatedOps) { - this.services = services; + public PaginationCompilationTestGenerator(PluginContext context, ServiceShape service, List> allPaginatedOps) { this.allPaginatedOps = allPaginatedOps; + this.parser = new CompilationTestParser<>( + context, + service, + allPaginatedOps, + "Pagination", + this::render + ); + } + + public void run() { + parser.run(); } public void render(CppWriter writer) { - String serviceName = getServiceName(services.get(0)); + // Get service from the first operation since all operations belong to the same service + ServiceShape service = allPaginatedOps.get(0).getService(); + String serviceName = getServiceName(service); writer.write("/**") .write(" * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.") @@ -72,4 +86,5 @@ private String getServiceName(ServiceShape service) { .replace("-", ""); } + } \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java new file mode 100644 index 000000000000..d90314a75e0f --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java @@ -0,0 +1,127 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.templates; + +import software.amazon.smithy.build.PluginContext; +import software.amazon.smithy.codegen.core.SymbolProvider; +import software.amazon.smithy.model.shapes.*; +import software.amazon.smithy.model.traits.PaginatedTrait; +import software.amazon.smithy.aws.traits.ServiceTrait; +import com.amazonaws.util.awsclientsmithygenerator.generators.OperationData; +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; +import java.util.*; + +public class PaginationTraitsGenerator { + private final PluginContext context; + private final ServiceShape service; + private final List> paginatedOps; + private final String c2jServiceName; + + private final CppWriterDelegator writerDelegator; + + public PaginationTraitsGenerator(PluginContext context, ServiceShape service, List> paginatedOps, String c2jServiceName) { + this.context = context; + this.service = service; + this.paginatedOps = paginatedOps; + this.c2jServiceName = c2jServiceName; + this.writerDelegator = new CppWriterDelegator(context.getFileManifest()); + } + + public void write() { + String serviceName = service.getTrait(ServiceTrait.class) + .map(ServiceTrait::getSdkId) + .orElse(service.getId().getName()) + .replace(" ", "") + .replace("-", ""); + + for (OperationData data : paginatedOps) { + String fileName = "include/aws/" + c2jServiceName + "/model/pagination/" + data.getOperation().getId().getName() + "PaginationTraits.h"; + + writerDelegator.useFileWriter(fileName, writer -> { + generateTraitsHeader(writer, data, serviceName); + }); + } + + writerDelegator.flushWriters(); + } + + private void generateTraitsHeader(CppWriter writer, OperationData data, String serviceName) { + OperationShape op = data.getOperation(); + PaginatedTrait trait = data.getTrait(); + String opName = op.getId().getName(); + + // Header comment + writer.write("/**") + .write(" * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.") + .write(" * SPDX-License-Identifier: Apache-2.0.") + .write(" */") + .write("") + .write("#pragma once"); + + // Includes + writer.writeInclude("aws/" + c2jServiceName + "/" + serviceName + "_EXPORTS.h") + .writeInclude("aws/" + c2jServiceName + "/model/" + opName + "Request.h") + .writeInclude("aws/" + c2jServiceName + "/model/" + opName + "Result.h") + .writeInclude("aws/" + c2jServiceName + "/" + serviceName + "Client.h") + .write(""); + + // Namespaces + writer.writeNamespaceOpen("Aws") + .writeNamespaceOpen(serviceName) + .writeNamespaceOpen("Pagination") + .write(""); + + // Struct definition + writer.openBlock("struct " + opName + "PaginationTraits\n{", "};", () -> { + writer.write(" using RequestType = Model::$LRequest;", opName) + .write(" using ResultType = Model::$LResult;", opName) + .write(" using OutcomeType = Model::$LOutcome;", opName) + .write(" using ClientType = $LClient;", serviceName) + .write(""); + + // Invoke method + writer.openBlock(" static OutcomeType Invoke(ClientType& client, const RequestType& request)\n {", " }", () -> { + writer.write(" return client.$L(request);", opName); + }); + + writer.write(""); + + // HasMoreResults method + writer.openBlock(" static bool HasMoreResults(const ResultType& result)\n {", " }", () -> { + if (trait.getOutputToken().isPresent()) { + String outToken = trait.getOutputToken().get(); + if (outToken.toLowerCase().contains("marker") || outToken.toLowerCase().contains("number")) { + writer.write(" return result.Get$L() != 0;", capitalize(outToken)); + } else { + writer.write(" return !result.Get$L().empty();", capitalize(outToken)); + } + } else { + writer.write(" return result.GetIsTruncated();"); + } + }); + + writer.write(""); + + // SetNextRequest method + writer.openBlock(" static void SetNextRequest(const ResultType& result, RequestType& request)\n {", " }", () -> { + if (trait.getInputToken().isPresent() && trait.getOutputToken().isPresent()) { + String inToken = trait.getInputToken().get(); + String outToken = trait.getOutputToken().get(); + writer.write(" request.Set$L(result.Get$L());", capitalize(inToken), capitalize(outToken)); + } + }); + }); + + writer.write("") + .writeNamespaceClose("Pagination") + .writeNamespaceClose(serviceName) + .writeNamespaceClose("Aws"); + } + + private String capitalize(String str) { + return str.substring(0, 1).toUpperCase() + str.substring(1); + } +} From 92c93c7bf7f767f484afbf5b631ef39f5080af53 Mon Sep 17 00:00:00 2001 From: kai lin Date: Thu, 15 Jan 2026 16:50:21 -0500 Subject: [PATCH 09/46] added service name util --- .../S3PaginationCompilationTests.cpp | 5 +-- .../generators/CompilationTestParser.java | 30 +++---------- .../generators/FeatureParser.java | 31 +++---------- .../generators/PaginationCodegenPlugin.java | 13 +++--- .../generators/ServiceNameUtil.java | 31 +++++++++++++ .../PaginationClientHeaderGenerator.java | 25 +++++------ .../PaginationCompilationTestGenerator.java | 44 +++++++++++-------- .../templates/PaginationTraitsGenerator.java | 8 +--- 8 files changed, 88 insertions(+), 99 deletions(-) create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java diff --git a/generated/tests/s3-gen-tests/S3PaginationCompilationTests.cpp b/generated/tests/s3-gen-tests/S3PaginationCompilationTests.cpp index 0fa4ac48c381..9ea1602aebcb 100644 --- a/generated/tests/s3-gen-tests/S3PaginationCompilationTests.cpp +++ b/generated/tests/s3-gen-tests/S3PaginationCompilationTests.cpp @@ -8,12 +8,9 @@ #include #include -#include #include -#include -#include -#include #include +#include #include diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CompilationTestParser.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CompilationTestParser.java index 4d7e1c5821c5..afcaac07d93b 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CompilationTestParser.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CompilationTestParser.java @@ -8,25 +8,24 @@ import software.amazon.smithy.model.shapes.*; import software.amazon.smithy.aws.traits.ServiceTrait; import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; +import com.amazonaws.util.awsclientsmithygenerator.generators.ServiceNameUtil; import java.util.*; import java.util.function.Consumer; public class CompilationTestParser { - private final PluginContext context; private final ServiceShape service; - private final List operations; private final CppWriterDelegator writerDelegator; private final String testType; private final Consumer renderFunction; + private final Map c2jMap; public CompilationTestParser(PluginContext context, ServiceShape service, List operations, - String testType, Consumer renderFunction) { - this.context = context; + String testType, Consumer renderFunction, Map c2jMap) { this.service = service; - this.operations = operations; this.writerDelegator = new CppWriterDelegator(context.getFileManifest()); this.testType = testType; this.renderFunction = renderFunction; + this.c2jMap = c2jMap; } public void run() { @@ -35,29 +34,12 @@ public void run() { } private void generateCompilationTest() { - String serviceName = getServiceName(service); - String c2jServiceName = getC2jServiceName(service); + String serviceName = ServiceNameUtil.getServiceName(service); + String c2jServiceName = ServiceNameUtil.getC2jServiceName(service, c2jMap); writerDelegator.useFileWriter( "generated/tests/" + c2jServiceName + "-gen-tests/" + serviceName + testType + "CompilationTests.cpp", renderFunction ); } - - private String getServiceName(ServiceShape service) { - return service.getTrait(ServiceTrait.class) - .map(ServiceTrait::getSdkId) - .orElse(service.getId().getName()) - .replace(" ", "") - .replace("-", ""); - } - - private String getC2jServiceName(ServiceShape service) { - return service.getTrait(ServiceTrait.class) - .map(ServiceTrait::getSdkId) - .orElse(service.getId().getName()) - .trim() - .toLowerCase() - .replace(" ", "-"); - } } \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/FeatureParser.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/FeatureParser.java index 53d2938e2457..4d70ac642efe 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/FeatureParser.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/FeatureParser.java @@ -5,7 +5,6 @@ package com.amazonaws.util.awsclientsmithygenerator.generators; import software.amazon.smithy.build.PluginContext; -import software.amazon.smithy.model.Model; import software.amazon.smithy.model.node.Node; import software.amazon.smithy.model.node.ObjectNode; import software.amazon.smithy.model.shapes.*; @@ -15,7 +14,6 @@ public class FeatureParser { private final PluginContext context; - private final Model model; private final ServiceShape service; private final List operations; private final CppWriterDelegator writerDelegator; @@ -24,7 +22,6 @@ public class FeatureParser { public FeatureParser(PluginContext context, ServiceShape service, List operations, String featureName) { this.context = context; - this.model = context.getModel(); this.service = service; this.operations = operations; this.featureName = featureName; @@ -51,8 +48,8 @@ public void run(Consumer> generationLogic) { } public void generateClientHeader(String fileName, Consumer generator) { - String serviceName = getServiceName(service); - String c2jServiceName = getC2jServiceName(service); + String serviceName = ServiceNameUtil.getServiceName(service); + String c2jServiceName = ServiceNameUtil.getC2jServiceName(service, c2jMap); writerDelegator.useFileWriter( "include/aws/" + c2jServiceName + "/" + fileName, @@ -64,25 +61,7 @@ public void generateClientHeader(String fileName, Consumer generator) public ServiceShape getService() { return service; } public List getOperations() { return operations; } public String getFeatureName() { return featureName; } - public String getServiceName() { return getServiceName(service); } - public String getC2jServiceName() { return getC2jServiceName(service); } - - private String getServiceName(ServiceShape service) { - return service.getTrait(ServiceTrait.class) - .map(ServiceTrait::getSdkId) - .orElse(service.getId().getName()) - .replace(" ", "") - .replace("-", ""); - } - - private String getC2jServiceName(ServiceShape service) { - String sdkId = service.getTrait(ServiceTrait.class) - .map(ServiceTrait::getSdkId) - .orElse(service.getId().getName()) - .trim() - .toLowerCase() - .replace(" ", "-"); - - return c2jMap.getOrDefault(sdkId, sdkId); - } + public Map getC2jMap() { return c2jMap; } + public String getServiceName() { return ServiceNameUtil.getServiceName(service); } + public String getC2jServiceName() { return ServiceNameUtil.getC2jServiceName(service, c2jMap); } } \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java index 1681570a7a7d..156bf97a7a3b 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java @@ -14,7 +14,6 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationTraitsGenerator; import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationClientHeaderGenerator; import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationCompilationTestGenerator; -import software.amazon.smithy.model.traits.PaginatedTrait; import java.util.List; import java.util.stream.Collectors; @@ -45,22 +44,22 @@ public void execute(PluginContext context) { // Generate client pagination header featureParser.generateClientHeader( serviceName + "ClientPagination.h", - writer -> new PaginationClientHeaderGenerator(featureParser.getService(), featureParser.getOperations()).render(writer) + writer -> new PaginationClientHeaderGenerator(featureParser.getService(), featureParser.getOperations(), featureParser.getC2jMap()).render(writer) ); // Generate pagination traits headers - PaginationTraitsGenerator headerWriter = new PaginationTraitsGenerator( + PaginationTraitsGenerator traitsGenerator = new PaginationTraitsGenerator( featureParser.getContext(), featureParser.getService(), featureParser.getOperations(), featureParser.getC2jServiceName() ); - headerWriter.write(); + traitsGenerator.write(); }); - // Generate header compilation test - PaginationCompilationTestGenerator headerGenerator = new PaginationCompilationTestGenerator(context, service, paginatedOps); - headerGenerator.run(); + // Generate compilation test + PaginationCompilationTestGenerator testGenerator = new PaginationCompilationTestGenerator(context, service, paginatedOps, parser.getC2jMap()); + testGenerator.run(); } } } diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java new file mode 100644 index 000000000000..2eb603adca35 --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java @@ -0,0 +1,31 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators; + +import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.aws.traits.ServiceTrait; +import java.util.Map; + +public final class ServiceNameUtil { + + public static String getServiceName(ServiceShape service) { + return service.getTrait(ServiceTrait.class) + .map(ServiceTrait::getSdkId) + .orElse(service.getId().getName()) + .replace(" ", "") + .replace("-", ""); + } + + public static String getC2jServiceName(ServiceShape service, Map c2jMap) { + String sdkId = service.getTrait(ServiceTrait.class) + .map(ServiceTrait::getSdkId) + .orElse(service.getId().getName()) + .trim() + .toLowerCase() + .replace(" ", "-"); + + return c2jMap != null ? c2jMap.getOrDefault(sdkId, sdkId) : sdkId; + } +} \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java index ff00f56872f6..e8d387637394 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java @@ -9,19 +9,24 @@ import software.amazon.smithy.model.shapes.ServiceShape; import software.amazon.smithy.aws.traits.ServiceTrait; import software.amazon.smithy.model.traits.PaginatedTrait; +import com.amazonaws.util.awsclientsmithygenerator.generators.ServiceNameUtil; import java.util.List; +import java.util.Map; public class PaginationClientHeaderGenerator { private final ServiceShape service; private final List> paginatedOps; + private final Map c2jMap; - public PaginationClientHeaderGenerator(ServiceShape service, List> paginatedOps) { + public PaginationClientHeaderGenerator(ServiceShape service, List> paginatedOps, Map c2jMap) { this.service = service; this.paginatedOps = paginatedOps; + this.c2jMap = c2jMap; } public void render(CppWriter writer) { - String serviceName = getServiceName(); + String serviceName = ServiceNameUtil.getServiceName(service); + String c2jServiceName = ServiceNameUtil.getC2jServiceName(service, c2jMap); // Header and includes writer.write("/**"); @@ -31,17 +36,17 @@ public void render(CppWriter writer) { writer.write(""); writer.write("#pragma once"); - renderIncludes(writer, serviceName); + renderIncludes(writer, serviceName, c2jServiceName); renderNamespaces(writer, serviceName); } - private void renderIncludes(CppWriter writer, String serviceName) { - writer.writeInclude("aws/" + serviceName.toLowerCase() + "/" + serviceName + "Client.h"); + private void renderIncludes(CppWriter writer, String serviceName, String c2jServiceName) { + writer.writeInclude("aws/" + c2jServiceName + "/" + serviceName + "Client.h"); writer.writeInclude("aws/core/utils/pagination/Paginator.h"); for (OperationData data : paginatedOps) { String opName = data.getOperation().getId().getName(); - writer.writeInclude("aws/" + serviceName.toLowerCase() + "/model/pagination/" + opName + "PaginationTraits.h"); + writer.writeInclude("aws/" + c2jServiceName + "/model/pagination/" + opName + "PaginationTraits.h"); } writer.write(""); } @@ -61,12 +66,4 @@ private void renderNamespaces(CppWriter writer, String serviceName) { writer.writeNamespaceClose(serviceName); writer.writeNamespaceClose("Aws"); } - - private String getServiceName() { - return service.getTrait(ServiceTrait.class) - .map(ServiceTrait::getSdkId) - .orElse(service.getId().getName()) - .replace(" ", "") - .replace("-", ""); - } } \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java index 155d2bcdac2c..69c7ee22dc1c 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java @@ -9,21 +9,25 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; import com.amazonaws.util.awsclientsmithygenerator.generators.CompilationTestParser; import com.amazonaws.util.awsclientsmithygenerator.generators.OperationData; +import com.amazonaws.util.awsclientsmithygenerator.generators.ServiceNameUtil; import software.amazon.smithy.model.traits.PaginatedTrait; import java.util.*; public class PaginationCompilationTestGenerator { private final CompilationTestParser> parser; private final List> allPaginatedOps; + private final Map c2jMap; - public PaginationCompilationTestGenerator(PluginContext context, ServiceShape service, List> allPaginatedOps) { + public PaginationCompilationTestGenerator(PluginContext context, ServiceShape service, List> allPaginatedOps, Map c2jMap) { this.allPaginatedOps = allPaginatedOps; + this.c2jMap = c2jMap; this.parser = new CompilationTestParser<>( context, service, allPaginatedOps, "Pagination", - this::render + this::render, + c2jMap ); } @@ -34,7 +38,7 @@ public void run() { public void render(CppWriter writer) { // Get service from the first operation since all operations belong to the same service ServiceShape service = allPaginatedOps.get(0).getService(); - String serviceName = getServiceName(service); + String serviceName = ServiceNameUtil.getServiceName(service); writer.write("/**") .write(" * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.") @@ -65,26 +69,30 @@ public void render(CppWriter writer) { } private void writeIncludes(CppWriter writer) { + Set clientHeaders = new HashSet<>(); + Set traitHeaders = new HashSet<>(); + for (OperationData paginationData : allPaginatedOps) { ServiceShape service = paginationData.getService(); - String serviceName = getServiceName(service); + String serviceName = ServiceNameUtil.getServiceName(service); + String c2jServiceName = ServiceNameUtil.getC2jServiceName(service, c2jMap); - // Include pagination client header - writer.writeInclude("aws/" + serviceName.toLowerCase() + "/" + serviceName + "ClientPagination.h"); + // Collect unique client headers + clientHeaders.add("aws/" + c2jServiceName + "/" + serviceName + "ClientPagination.h"); - // Include pagination traits headers + // Collect unique trait headers String operationName = paginationData.getOperation().getId().getName(); - writer.writeInclude("aws/" + serviceName.toLowerCase() + "/model/pagination/" + operationName + "PaginationTraits.h"); + traitHeaders.add("aws/" + c2jServiceName + "/model/pagination/" + operationName + "PaginationTraits.h"); + } + + // Write unique client headers + for (String header : clientHeaders) { + writer.writeInclude(header); + } + + // Write unique trait headers + for (String header : traitHeaders) { + writer.writeInclude(header); } } - - private String getServiceName(ServiceShape service) { - return service.getTrait(software.amazon.smithy.aws.traits.ServiceTrait.class) - .map(software.amazon.smithy.aws.traits.ServiceTrait::getSdkId) - .orElse(service.getId().getName()) - .replace(" ", "") - .replace("-", ""); - } - - } \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java index d90314a75e0f..e00baff6d8b9 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java @@ -5,13 +5,13 @@ package com.amazonaws.util.awsclientsmithygenerator.generators.templates; import software.amazon.smithy.build.PluginContext; -import software.amazon.smithy.codegen.core.SymbolProvider; import software.amazon.smithy.model.shapes.*; import software.amazon.smithy.model.traits.PaginatedTrait; import software.amazon.smithy.aws.traits.ServiceTrait; import com.amazonaws.util.awsclientsmithygenerator.generators.OperationData; import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; +import com.amazonaws.util.awsclientsmithygenerator.generators.ServiceNameUtil; import java.util.*; public class PaginationTraitsGenerator { @@ -31,11 +31,7 @@ public PaginationTraitsGenerator(PluginContext context, ServiceShape service, Li } public void write() { - String serviceName = service.getTrait(ServiceTrait.class) - .map(ServiceTrait::getSdkId) - .orElse(service.getId().getName()) - .replace(" ", "") - .replace("-", ""); + String serviceName = ServiceNameUtil.getServiceName(service); for (OperationData data : paginatedOps) { String fileName = "include/aws/" + c2jServiceName + "/model/pagination/" + data.getOperation().getId().getName() + "PaginationTraits.h"; From bf937a92fc802bb494efaed579babfe5a556233b Mon Sep 17 00:00:00 2001 From: kai lin Date: Thu, 15 Jan 2026 17:55:19 -0500 Subject: [PATCH 10/46] filter out deprecated service --- .../generators/PaginationCodegenPlugin.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java index 156bf97a7a3b..bd64ffd5c9a2 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java @@ -8,6 +8,7 @@ import software.amazon.smithy.build.SmithyBuildPlugin; import software.amazon.smithy.model.knowledge.TopDownIndex; import software.amazon.smithy.model.traits.PaginatedTrait; +import software.amazon.smithy.model.traits.DeprecatedTrait; import software.amazon.smithy.model.shapes.*; import com.amazonaws.util.awsclientsmithygenerator.generators.OperationData; import com.amazonaws.util.awsclientsmithygenerator.generators.FeatureParser; @@ -29,9 +30,10 @@ public void execute(PluginContext context) { var model = context.getModel(); for (ServiceShape service : model.getServiceShapes()) { - // Find paginated operations using TopDownIndex + // Find paginated operations using TopDownIndex, excluding deprecated operations List> paginatedOps = TopDownIndex.of(model).getContainedOperations(service).stream() .filter(op -> op.hasTrait(PaginatedTrait.class)) + .filter(op -> !op.hasTrait(DeprecatedTrait.class)) .map(op -> new OperationData<>(op, op.expectTrait(PaginatedTrait.class), service)) .collect(Collectors.toList()); From f070b257a1b32b65db944e1be0171d60e5a0f510 Mon Sep 17 00:00:00 2001 From: kai lin Date: Fri, 16 Jan 2026 15:20:46 -0500 Subject: [PATCH 11/46] edgecases for backwards compatibility --- .../generators/ServiceNameUtil.java | 30 +++++++++++++++++++ .../templates/PaginationTraitsGenerator.java | 24 +++++++++++++-- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java index 2eb603adca35..e9f92b9ac549 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java @@ -6,11 +6,41 @@ import software.amazon.smithy.model.shapes.ServiceShape; import software.amazon.smithy.aws.traits.ServiceTrait; +import software.amazon.smithy.model.traits.TitleTrait; import java.util.Map; +import java.util.Set; public final class ServiceNameUtil { + // Legacy service IDs that need special handling to match what the legacy c2j code generator produced + // This logic is copied from C2jModelToGeneratorModelTransformer.convertMetadata() method + private static final Set LEGACY_SERVICE_IDS = Set.of( + "amp", "appintegrations", "amazonappintegrationservice", "billingconductor", "clouddirectory", "cloudfront", + "cloudsearch", "cloudsearchdomain", "codeartifact", "codestar-notifications", + "config", "databrew", "ec2", "elasticache", "emr-containers", + "entitlement.marketplace", "events", "evidently", "forecast", "forecastquery", + "grafana", "importexport", "inspector", "lambda", "location", "lookoutvision", + "m2", "migrationhubstrategy", "mobile", "mobileanalytics", "mq", "nimble", + "opensearch", "rbin", "rds-data", "redshift-data", "resiliencehub", "rum", + "sagemaker-a2i-runtime", "sagemaker-edge", "schemas", "sdb", "transcribe", + "transcribe-streaming", "wisdom", "lex", "lexv2-runtime", "lexv2-models", + "marketplace-entitlement", "sagemaker-runtime", "awstransfer", "transcribestreaming", + "dynamodbstreams" + ); + public static String getServiceName(ServiceShape service) { + String serviceName = service.getId().getName().toLowerCase(); + if (LEGACY_SERVICE_IDS.contains(serviceName)) { + // For legacy services, use title trait which includes "Service" suffix + String title = service.getTrait(TitleTrait.class) + .map(TitleTrait::getValue) + .orElse(null); + if (title != null) { + return title.replace(" ", "").replace("-", "").replace("Amazon", "").replace("AWS", ""); + } + } + + // For new services or legacy without title, use serviceId trait return service.getTrait(ServiceTrait.class) .map(ServiceTrait::getSdkId) .orElse(service.getId().getName()) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java index e00baff6d8b9..ffe24b749a4d 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java @@ -13,6 +13,7 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; import com.amazonaws.util.awsclientsmithygenerator.generators.ServiceNameUtil; import java.util.*; +import java.util.Arrays; public class PaginationTraitsGenerator { private final PluginContext context; @@ -57,10 +58,11 @@ private void generateTraitsHeader(CppWriter writer, OperationData { + // Use detected suffix to match C2J renameShape logic writer.write(" using RequestType = Model::$LRequest;", opName) - .write(" using ResultType = Model::$LResult;", opName) + .write(" using ResultType = Model::$L$L;", opName, resultSuffix) .write(" using OutcomeType = Model::$LOutcome;", opName) .write(" using ClientType = $LClient;", serviceName) .write(""); @@ -117,6 +120,21 @@ private void generateTraitsHeader(CppWriter writer, OperationData Date: Fri, 16 Jan 2026 15:25:32 -0500 Subject: [PATCH 12/46] edgecases for backwards compatibility --- .../generators/templates/PaginationTraitsGenerator.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java index ffe24b749a4d..d4470b62b134 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java @@ -120,6 +120,8 @@ private void generateTraitsHeader(CppWriter writer, OperationData Date: Fri, 16 Jan 2026 16:50:26 -0500 Subject: [PATCH 13/46] temporary fix for AccessAnalyzer which uses service-level pagination config --- .../generators/CppWriter.java | 4 +- .../templates/PaginationTraitsGenerator.java | 64 ++++++++++++++++++- 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java index bf1ad4ffc53b..d3729c6223e6 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CppWriter.java @@ -34,12 +34,12 @@ public CppWriter writeInclude(String header) { } public CppWriter writeNamespaceOpen(String namespace) { - write("namespace $L\n{", namespace); + openBlock("namespace $L\n{", namespace); return this; } public CppWriter writeNamespaceClose(String namespace) { - write("} // namespace $L", namespace); + closeBlock("} // namespace $L", namespace); return this; } } \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java index d4470b62b134..b7b4469992de 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java @@ -98,7 +98,21 @@ private void generateTraitsHeader(CppWriter writer, OperationData { + String inToken = null; + String outToken = null; + if (trait.getInputToken().isPresent() && trait.getOutputToken().isPresent()) { - String inToken = trait.getInputToken().get(); - String outToken = trait.getOutputToken().get(); + inToken = trait.getInputToken().get(); + outToken = trait.getOutputToken().get(); + } else { + // TODO: Check how legacy C2J code generation handles service-level pagination + // This is a temporary fix for AccessAnalyzer which uses service-level pagination config. + // We should investigate how the legacy generator in C2jModelToGeneratorModelTransformer + // or other legacy components handle service-level vs operation-level pagination traits + // and implement a more comprehensive solution that matches that behavior. + String serviceLevelInputToken = getServiceLevelInputToken(); + String serviceLevelOutputToken = getServiceLevelOutputToken(); + if (serviceLevelInputToken != null && serviceLevelOutputToken != null) { + inToken = serviceLevelInputToken; + outToken = serviceLevelOutputToken; + } + } + + if (inToken != null && outToken != null) { writer.write(" request.Set$L(result.Get$L());", capitalize(inToken), capitalize(outToken)); + } else { + // TODO: Check AWS SDK C++ standard for handling null pagination tokens + // Should we throw an exception, log a warning, or silently ignore? + // Verify behavior with other AWS SDK implementations. + writer.write(" (void)result; (void)request; // Unused parameters"); } }); }); @@ -137,6 +174,27 @@ private boolean isEc2Protocol() { return "ec2".equals(c2jServiceName); } + // TODO: These service-level pagination helper methods are a temporary solution. + // We should investigate how the legacy C2J code generation system handles the precedence + // between operation-level and service-level pagination traits, and implement a solution + // that matches that behavior. This may involve: + // 1. Checking how C2jModelToGeneratorModelTransformer processes pagination + // 2. Understanding the inheritance model for pagination traits + // 3. Implementing proper trait resolution that matches legacy behavior + private String getServiceLevelInputToken() { + // Check if service has service-level pagination configuration + return service.getTrait(software.amazon.smithy.model.traits.PaginatedTrait.class) + .map(trait -> trait.getInputToken().orElse(null)) + .orElse(null); + } + + private String getServiceLevelOutputToken() { + // Check if service has service-level pagination configuration + return service.getTrait(software.amazon.smithy.model.traits.PaginatedTrait.class) + .map(trait -> trait.getOutputToken().orElse(null)) + .orElse(null); + } + private String capitalize(String str) { return str.substring(0, 1).toUpperCase() + str.substring(1); } From ed27556c82e7d350baa596ec39e334ecf97eca6c Mon Sep 17 00:00:00 2001 From: kai lin Date: Fri, 16 Jan 2026 20:21:33 -0500 Subject: [PATCH 14/46] temporary fix for amp --- .../generators/ServiceNameUtil.java | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java index e9f92b9ac549..2dc274678274 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java @@ -17,7 +17,7 @@ public final class ServiceNameUtil { private static final Set LEGACY_SERVICE_IDS = Set.of( "amp", "appintegrations", "amazonappintegrationservice", "billingconductor", "clouddirectory", "cloudfront", "cloudsearch", "cloudsearchdomain", "codeartifact", "codestar-notifications", - "config", "databrew", "ec2", "elasticache", "emr-containers", + "config", "databrew", "elasticache", "emr-containers", "entitlement.marketplace", "events", "evidently", "forecast", "forecastquery", "grafana", "importexport", "inspector", "lambda", "location", "lookoutvision", "m2", "migrationhubstrategy", "mobile", "mobileanalytics", "mq", "nimble", @@ -29,23 +29,30 @@ public final class ServiceNameUtil { ); public static String getServiceName(ServiceShape service) { - String serviceName = service.getId().getName().toLowerCase(); - if (LEGACY_SERVICE_IDS.contains(serviceName)) { - // For legacy services, use title trait which includes "Service" suffix + // TODO: This logic should match C2jModelToGeneratorModelTransformer.convertMetadata() + // to ensure consistent service name generation between legacy and new generators + + String serviceId = service.getTrait(ServiceTrait.class) + .map(ServiceTrait::getSdkId) + .orElse(service.getId().getName()); + + if (LEGACY_SERVICE_IDS.contains(serviceId.toLowerCase())) { + // For legacy services, use title trait (serviceFullName equivalent) which includes "Service" suffix String title = service.getTrait(TitleTrait.class) .map(TitleTrait::getValue) .orElse(null); if (title != null) { - return title.replace(" ", "").replace("-", "").replace("Amazon", "").replace("AWS", ""); + return sanitizeServiceAbbreviation(title); } } // For new services or legacy without title, use serviceId trait - return service.getTrait(ServiceTrait.class) - .map(ServiceTrait::getSdkId) - .orElse(service.getId().getName()) - .replace(" ", "") - .replace("-", ""); + return sanitizeServiceAbbreviation(serviceId); + } + + // Match C2jModelToGeneratorModelTransformer.sanitizeServiceAbbreviation() exactly + private static String sanitizeServiceAbbreviation(String serviceAbbreviation) { + return serviceAbbreviation.replace(" ", "").replace("-", "").replace("_", "").replace("Amazon", "").replace("AWS", "").replace("/", ""); } public static String getC2jServiceName(ServiceShape service, Map c2jMap) { From 003c82938fd78e93fb12b89ec0bbb8b32023cc57 Mon Sep 17 00:00:00 2001 From: kai lin Date: Sat, 17 Jan 2026 01:20:02 -0500 Subject: [PATCH 15/46] temporary fix for B2BI --- .../generators/ServiceNameUtil.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java index 2dc274678274..748b719e05dc 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java @@ -35,6 +35,14 @@ public static String getServiceName(ServiceShape service) { String serviceId = service.getTrait(ServiceTrait.class) .map(ServiceTrait::getSdkId) .orElse(service.getId().getName()); + + //TODO: bandage fix + // For B2BI and other services, check if we have a serviceAbbreviation equivalent + // The main generator uses serviceAbbreviation ("AWS B2BI") -> sanitized -> "B2BI" + // We need to simulate this for consistency + if ("b2bi".equals(serviceId.toLowerCase())) { + return "B2BI"; // Match the main generator's output + } if (LEGACY_SERVICE_IDS.contains(serviceId.toLowerCase())) { // For legacy services, use title trait (serviceFullName equivalent) which includes "Service" suffix From 129efb747bdc8c548f83cf24d5c3210ff53fa1c8 Mon Sep 17 00:00:00 2001 From: kai lin Date: Sat, 17 Jan 2026 02:01:51 -0500 Subject: [PATCH 16/46] harded for missing abbreviation trait --- .../generators/ServiceNameUtil.java | 45 +++++++++++++------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java index 748b719e05dc..94153fc6f0f7 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java @@ -28,24 +28,44 @@ public final class ServiceNameUtil { "dynamodbstreams" ); + // TODO: Remove hardcoded mappings once Smithy models include serviceAbbreviation trait + // Smithy sdkId matches C2J serviceId, but C2J prioritizes serviceAbbreviation (which Smithy lacks). + // 18 of 66 services where C2J abbrev != serviceId require these mappings to match C2J output. + // Hardcoded mappings where Smithy sdkId doesn't match C2J serviceAbbreviation + private static final Map SMITHY_TO_C2J_NAMESPACE = Map.ofEntries( + Map.entry("b2bi", "B2BI"), + Map.entry("cloudcontrol", "CloudControlApi"), + Map.entry("ecrpublic", "ECRPublic"), + Map.entry("evs", "EVS"), + Map.entry("finspacedata", "FinSpaceData"), + Map.entry("fis", "FIS"), + Map.entry("identitystore", "IdentityStore"), + Map.entry("inspectorscan", "inspectorscan"), + Map.entry("iotdeviceadvisor", "IoTDeviceAdvisor"), + Map.entry("ivs", "IVS"), + Map.entry("ivsrealtime", "ivsrealtime"), + Map.entry("kinesisvideosignaling", "KinesisVideoSignalingChannels"), + Map.entry("marketplaceagreement", "AgreementService"), + Map.entry("mediapackagev2", "mediapackagev2"), + Map.entry("savingsplans", "SavingsPlans"), + Map.entry("servicecatalogappregistry", "AppRegistry"), + Map.entry("sesv2", "SESV2"), + Map.entry("synthetics", "Synthetics") + ); + public static String getServiceName(ServiceShape service) { - // TODO: This logic should match C2jModelToGeneratorModelTransformer.convertMetadata() - // to ensure consistent service name generation between legacy and new generators - String serviceId = service.getTrait(ServiceTrait.class) .map(ServiceTrait::getSdkId) .orElse(service.getId().getName()); - - //TODO: bandage fix - // For B2BI and other services, check if we have a serviceAbbreviation equivalent - // The main generator uses serviceAbbreviation ("AWS B2BI") -> sanitized -> "B2BI" - // We need to simulate this for consistency - if ("b2bi".equals(serviceId.toLowerCase())) { - return "B2BI"; // Match the main generator's output + + // Check hardcoded mappings first + String sanitized = sanitizeServiceAbbreviation(serviceId); + String mapped = SMITHY_TO_C2J_NAMESPACE.get(sanitized.toLowerCase()); + if (mapped != null) { + return mapped; } if (LEGACY_SERVICE_IDS.contains(serviceId.toLowerCase())) { - // For legacy services, use title trait (serviceFullName equivalent) which includes "Service" suffix String title = service.getTrait(TitleTrait.class) .map(TitleTrait::getValue) .orElse(null); @@ -54,8 +74,7 @@ public static String getServiceName(ServiceShape service) { } } - // For new services or legacy without title, use serviceId trait - return sanitizeServiceAbbreviation(serviceId); + return sanitized; } // Match C2jModelToGeneratorModelTransformer.sanitizeServiceAbbreviation() exactly From cd521acde42dbb1bd24f06a0acdeff6aea202b1b Mon Sep 17 00:00:00 2001 From: kai lin Date: Sat, 17 Jan 2026 10:55:19 -0500 Subject: [PATCH 17/46] added new detection logic for conflicting service name and add sdk suffix --- .../templates/PaginationTraitsGenerator.java | 52 +++++++++++++++++-- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java index b7b4469992de..e772b769b4fc 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java @@ -157,23 +157,69 @@ private void generateTraitsHeader(CppWriter writer, OperationData suffixOptions = Arrays.asList("Result", "SdkResult", "CppSdkResult"); + + for (String suffix : suffixOptions) { + String candidateName = opName + suffix; + + // Check if there would be a naming conflict with this suffix + if (!hasNamingConflict(candidateName, opName)) { + return suffix; + } + } + + // Fallback to "Result" if no conflicts detected return "Result"; } + // Replicate the conflict detection logic from C2jModelToGeneratorModelTransformer + private boolean hasNamingConflict(String candidateName, String opName) { + // Check if there's a shape that would conflict with this name + // This mimics the conflict detection in renameShape method lines 771-775 + + // Get all shapes in the model to check for conflicts + Set allShapes = context.getModel().toSet(); + + for (Shape shape : allShapes) { + String shapeName = shape.getId().getName(); + + // Check if the candidate name conflicts with existing shape names + if (candidateName.equals(shapeName)) { + // There's a direct name conflict, need to use next suffix + return true; + } + + // Check for "Get" + shapeName pattern conflicts (from C2J logic) + if (candidateName.equals("Get" + shapeName) || candidateName.equals("Set" + shapeName)) { + return true; + } + } + + return false; + } + + // Remove the hardcoded method - no longer needed + // private boolean isKnownConflictingOperation(String opName) { ... } + private boolean isEc2Protocol() { // EC2 protocol services rename all Result shapes to Response // This matches the logic in Ec2CppClientGenerator.legacyPatchEc2Model return "ec2".equals(c2jServiceName); } + // TODO: These service-level pagination helper methods are a temporary solution. // We should investigate how the legacy C2J code generation system handles the precedence // between operation-level and service-level pagination traits, and implement a solution From 244eff9f0ba81c33e10c905879e0138f401ad072 Mon Sep 17 00:00:00 2001 From: kai lin Date: Sat, 17 Jan 2026 12:35:11 -0500 Subject: [PATCH 18/46] added new new detection logic for conflicting service name and add sdk suffix --- .../templates/PaginationTraitsGenerator.java | 64 +++++++++++-------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java index e772b769b4fc..585e7ae963bc 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java @@ -158,7 +158,7 @@ private void generateTraitsHeader(CppWriter writer, OperationData suffixOptions = Arrays.asList("Result", "SdkResult", "CppSdkResult"); + // For now, use the simple approach that works: + // If the actual generated file exists, use Result; otherwise use SdkResult - for (String suffix : suffixOptions) { - String candidateName = opName + suffix; + // Check for known SdkResult cases (where data model conflicts exist) + Set allShapes = context.getModel().toSet(); + boolean hasDataModelConflict = allShapes.stream() + .anyMatch(shape -> { + String shapeName = shape.getId().getName(); + if (shapeName.equals(opName + "Result")) { + // Found a shape with the same name - check if it's a data model + if (shape instanceof StructureShape) { + StructureShape structShape = (StructureShape) shape; + // If it doesn't have NextToken, it's likely a data model + return !structShape.getAllMembers().keySet().contains("NextToken"); + } + } + return false; + }); - // Check if there would be a naming conflict with this suffix - if (!hasNamingConflict(candidateName, opName)) { - return suffix; - } - } - - // Fallback to "Result" if no conflicts detected - return "Result"; + return hasDataModelConflict ? "SdkResult" : "Result"; } - // Replicate the conflict detection logic from C2jModelToGeneratorModelTransformer + // TODO: Delete this method if it's not used - replaced by simpler conflict detection in getResultSuffix + // Replicate the precise conflict detection logic from C2jModelToGeneratorModelTransformer private boolean hasNamingConflict(String candidateName, String opName) { - // Check if there's a shape that would conflict with this name - // This mimics the conflict detection in renameShape method lines 771-775 - // Get all shapes in the model to check for conflicts Set allShapes = context.getModel().toSet(); for (Shape shape : allShapes) { String shapeName = shape.getId().getName(); - // Check if the candidate name conflicts with existing shape names + // Direct exact name conflict - this is the main case if (candidateName.equals(shapeName)) { - // There's a direct name conflict, need to use next suffix - return true; - } - - // Check for "Get" + shapeName pattern conflicts (from C2J logic) - if (candidateName.equals("Get" + shapeName) || candidateName.equals("Set" + shapeName)) { + // If this is a structure, check if it's already a suitable operation result + if (shape instanceof StructureShape) { + StructureShape structShape = (StructureShape) shape; + // If the existing shape has pagination tokens, it's already an operation result - no conflict + // Check for various pagination token field names + boolean hasNextToken = structShape.getAllMembers().keySet().stream() + .anyMatch(memberName -> memberName.toLowerCase().contains("nexttoken") || + memberName.toLowerCase().contains("token")); + + if (hasNextToken) { + // This is already an operation result shape, no conflict + return false; + } + + // If it doesn't have pagination tokens, it's a data model - conflict! + return true; + } return true; } } From fe74f8f58d21de387ade127290d3d89fa4f6fd95 Mon Sep 17 00:00:00 2001 From: kai lin Date: Sat, 17 Jan 2026 14:06:11 -0500 Subject: [PATCH 19/46] added new new new detection logic (next/Next token) for conflicting service name and add sdk suffix --- .../generators/templates/PaginationTraitsGenerator.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java index 585e7ae963bc..c2fd9c7b5aae 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java @@ -179,8 +179,11 @@ private String getResultSuffix(String opName) { // Found a shape with the same name - check if it's a data model if (shape instanceof StructureShape) { StructureShape structShape = (StructureShape) shape; - // If it doesn't have NextToken, it's likely a data model - return !structShape.getAllMembers().keySet().contains("NextToken"); + // If it doesn't have NextToken/nextToken, it's likely a data model + Set memberNames = structShape.getAllMembers().keySet(); + // TODO: Sanitize member names for other edge cases (e.g., different casing, underscores, etc.) + boolean hasNextToken = memberNames.contains("NextToken") || memberNames.contains("nextToken"); + return !hasNextToken; } } return false; From e78e70d5b99ed89f666a8e08323abe618c77cfd2 Mon Sep 17 00:00:00 2001 From: kai lin Date: Tue, 20 Jan 2026 11:54:35 -0500 Subject: [PATCH 20/46] added a patch for Chatbotclient paginator. CamelCase --- .../generators/ServiceNameUtil.java | 13 +++++++++++++ .../templates/PaginationClientHeaderGenerator.java | 5 +++-- .../templates/PaginationTraitsGenerator.java | 7 ++++--- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java index 94153fc6f0f7..3bba5ef15fbf 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java @@ -77,6 +77,19 @@ public static String getServiceName(ServiceShape service) { return sanitized; } + // TODO: Investigate if getServiceNameLowercase and getServiceNameUpperCamel can be refactored + // to replace getServiceName entirely, ensuring all existing functionality is preserved + public static String getServiceNameLowercase(ServiceShape service) { + return getServiceName(service).toLowerCase(); + } + + // TODO: Investigate if getServiceNameLowercase and getServiceNameUpperCamel can be refactored + // to replace getServiceName entirely, ensuring all existing functionality is preserved + public static String getServiceNameUpperCamel(ServiceShape service) { + String serviceName = getServiceName(service); + return serviceName.substring(0, 1).toUpperCase() + serviceName.substring(1); + } + // Match C2jModelToGeneratorModelTransformer.sanitizeServiceAbbreviation() exactly private static String sanitizeServiceAbbreviation(String serviceAbbreviation) { return serviceAbbreviation.replace(" ", "").replace("-", "").replace("_", "").replace("Amazon", "").replace("AWS", "").replace("/", ""); diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java index e8d387637394..ff38b812abe8 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java @@ -41,7 +41,8 @@ public void render(CppWriter writer) { } private void renderIncludes(CppWriter writer, String serviceName, String c2jServiceName) { - writer.writeInclude("aws/" + c2jServiceName + "/" + serviceName + "Client.h"); + String capitalizedServiceName = ServiceNameUtil.getServiceNameUpperCamel(service); + writer.writeInclude("aws/" + c2jServiceName + "/" + capitalizedServiceName + "Client.h"); writer.writeInclude("aws/core/utils/pagination/Paginator.h"); for (OperationData data : paginatedOps) { @@ -59,7 +60,7 @@ private void renderNamespaces(CppWriter writer, String serviceName) { for (OperationData data : paginatedOps) { String opName = data.getOperation().getId().getName(); writer.write("using $LPaginator = Aws::Utils::Pagination::PagePaginator<$LClient, Model::$LRequest, Pagination::$LPaginationTraits>;", - opName, serviceName, opName, opName); + opName, ServiceNameUtil.getServiceNameUpperCamel(service), opName, opName); } writer.write(""); diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java index c2fd9c7b5aae..d0b914d76f67 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java @@ -60,10 +60,11 @@ private void generateTraitsHeader(CppWriter writer, OperationData Date: Tue, 20 Jan 2026 15:43:50 -0500 Subject: [PATCH 21/46] added a patch for cloudfront. uses a new suffix 2020_05_31 --- .../pagination/ListPartsPaginationTraits.h | 2 +- .../generators/ServiceNameUtil.java | 18 +++ .../PaginationClientHeaderGenerator.java | 5 +- .../templates/PaginationTraitsGenerator.java | 151 +++++++++++------- 4 files changed, 120 insertions(+), 56 deletions(-) diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h index dc6a20a510d9..2a847a744eca 100644 --- a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h @@ -21,7 +21,7 @@ struct ListPartsPaginationTraits { static OutcomeType Invoke(ClientType& client, const RequestType& request) { return client.ListParts(request); } - static bool HasMoreResults(const ResultType& result) { return result.GetNextPartNumberMarker() != 0; } + static bool HasMoreResults(const ResultType& result) { return !result.GetNextPartNumberMarker().empty(); } static void SetNextRequest(const ResultType& result, RequestType& request) { request.SetPartNumberMarker(result.GetNextPartNumberMarker()); diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java index 3bba5ef15fbf..2b54e2842316 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java @@ -105,4 +105,22 @@ public static String getC2jServiceName(ServiceShape service, Map return c2jMap != null ? c2jMap.getOrDefault(sdkId, sdkId) : sdkId; } + + /** + * Gets the client method name for an operation. + * CloudFront requires a version suffix for backwards compatibility with legacy C2J code generation. + * The legacy C2J generator appended version suffixes to CloudFront operation names in the generated code. + * + * TODO: Consider moving to a map if more services require version suffixes in the future + * + * @param opName The base operation name from the Smithy model + * @param c2jServiceName The C2J service name (e.g., "cloudfront") + * @return The operation name with version suffix if needed (e.g., "ListDistributions2020_05_31") + */ + public static String getClientMethodName(String opName, String c2jServiceName) { + if ("cloudfront".equals(c2jServiceName)) { + return opName + "2020_05_31"; + } + return opName; + } } \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java index ff38b812abe8..4e8d04768310 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java @@ -17,11 +17,13 @@ public class PaginationClientHeaderGenerator { private final ServiceShape service; private final List> paginatedOps; private final Map c2jMap; + private final String c2jServiceName; public PaginationClientHeaderGenerator(ServiceShape service, List> paginatedOps, Map c2jMap) { this.service = service; this.paginatedOps = paginatedOps; this.c2jMap = c2jMap; + this.c2jServiceName = ServiceNameUtil.getC2jServiceName(service, c2jMap); } public void render(CppWriter writer) { @@ -59,8 +61,9 @@ private void renderNamespaces(CppWriter writer, String serviceName) { for (OperationData data : paginatedOps) { String opName = data.getOperation().getId().getName(); + String methodName = ServiceNameUtil.getClientMethodName(opName, c2jServiceName); writer.write("using $LPaginator = Aws::Utils::Pagination::PagePaginator<$LClient, Model::$LRequest, Pagination::$LPaginationTraits>;", - opName, ServiceNameUtil.getServiceNameUpperCamel(service), opName, opName); + opName, ServiceNameUtil.getServiceNameUpperCamel(service), methodName, opName); } writer.write(""); diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java index d0b914d76f67..9e89383d3deb 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java @@ -61,9 +61,11 @@ private void generateTraitsHeader(CppWriter writer, OperationData { // Use detected suffix to match C2J renameShape logic - writer.write(" using RequestType = Model::$LRequest;", opName) - .write(" using ResultType = Model::$L$L;", opName, resultSuffix) - .write(" using OutcomeType = Model::$LOutcome;", opName) + String methodName = ServiceNameUtil.getClientMethodName(opName, c2jServiceName); + writer.write(" using RequestType = Model::$LRequest;", methodName) + .write(" using ResultType = Model::$L$L;", methodName, resultSuffix) + .write(" using OutcomeType = Model::$LOutcome;", methodName) .write(" using ClientType = $LClient;", capitalizedServiceName) .write(""); // Invoke method writer.openBlock(" static OutcomeType Invoke(ClientType& client, const RequestType& request)\n {", " }", () -> { - writer.write(" return client.$L(request);", opName); + writer.write(" return client.$L(request);", methodName); }); writer.write(""); @@ -93,7 +96,11 @@ private void generateTraitsHeader(CppWriter writer, OperationData { if (trait.getOutputToken().isPresent()) { String outToken = trait.getOutputToken().get(); - if (outToken.toLowerCase().contains("marker") || outToken.toLowerCase().contains("number")) { + String nestedListMember = getNestedListMember(op); + String tokenName = extractTokenName(outToken); + if (nestedListMember != null) { + writer.write(" return !result.Get$L().Get$L().empty();", capitalize(nestedListMember), capitalize(tokenName)); + } else if (isNumericToken(op, outToken)) { writer.write(" return result.Get$L() != 0;", capitalize(outToken)); } else { writer.write(" return !result.Get$L().empty();", capitalize(outToken)); @@ -142,7 +149,13 @@ private void generateTraitsHeader(CppWriter writer, OperationData allShapes = context.getModel().toSet(); boolean hasDataModelConflict = allShapes.stream() .anyMatch(shape -> { String shapeName = shape.getId().getName(); - if (shapeName.equals(opName + "Result")) { - // Found a shape with the same name - check if it's a data model + // Check if there's a conflicting shape with the base name + "Result" + String candidateName = baseOpName + "Result"; + if (shapeName.equals(candidateName)) { + // Found a shape with the same name - check if it's a data model (not an operation result) if (shape instanceof StructureShape) { StructureShape structShape = (StructureShape) shape; - // If it doesn't have NextToken/nextToken, it's likely a data model + // Check if this is an operation result by looking for pagination-related patterns Set memberNames = structShape.getAllMembers().keySet(); - // TODO: Sanitize member names for other edge cases (e.g., different casing, underscores, etc.) - boolean hasNextToken = memberNames.contains("NextToken") || memberNames.contains("nextToken"); - return !hasNextToken; + + // Direct pagination tokens + boolean hasDirectPaginationTokens = memberNames.contains("NextToken") || memberNames.contains("nextToken") || + memberNames.contains("Marker") || memberNames.contains("marker") || + memberNames.contains("NextMarker") || memberNames.contains("nextMarker") || + memberNames.contains("IsTruncated") || memberNames.contains("isTruncated"); + + // Check for nested list structures (common in AWS APIs) + boolean hasNestedListStructure = memberNames.stream() + .anyMatch(memberName -> memberName.toLowerCase().contains("list")); + + // If it has direct pagination tokens or nested list structure, it's likely an operation result + boolean isOperationResult = hasDirectPaginationTokens || hasNestedListStructure; + + return !isOperationResult; } } return false; @@ -193,44 +225,6 @@ private String getResultSuffix(String opName) { return hasDataModelConflict ? "SdkResult" : "Result"; } - // TODO: Delete this method if it's not used - replaced by simpler conflict detection in getResultSuffix - // Replicate the precise conflict detection logic from C2jModelToGeneratorModelTransformer - private boolean hasNamingConflict(String candidateName, String opName) { - // Get all shapes in the model to check for conflicts - Set allShapes = context.getModel().toSet(); - - for (Shape shape : allShapes) { - String shapeName = shape.getId().getName(); - - // Direct exact name conflict - this is the main case - if (candidateName.equals(shapeName)) { - // If this is a structure, check if it's already a suitable operation result - if (shape instanceof StructureShape) { - StructureShape structShape = (StructureShape) shape; - // If the existing shape has pagination tokens, it's already an operation result - no conflict - // Check for various pagination token field names - boolean hasNextToken = structShape.getAllMembers().keySet().stream() - .anyMatch(memberName -> memberName.toLowerCase().contains("nexttoken") || - memberName.toLowerCase().contains("token")); - - if (hasNextToken) { - // This is already an operation result shape, no conflict - return false; - } - - // If it doesn't have pagination tokens, it's a data model - conflict! - return true; - } - return true; - } - } - - return false; - } - - // Remove the hardcoded method - no longer needed - // private boolean isKnownConflictingOperation(String opName) { ... } - private boolean isEc2Protocol() { // EC2 protocol services rename all Result shapes to Response // This matches the logic in Ec2CppClientGenerator.legacyPatchEc2Model @@ -262,4 +256,53 @@ private String getServiceLevelOutputToken() { private String capitalize(String str) { return str.substring(0, 1).toUpperCase() + str.substring(1); } + + private String extractTokenName(String outToken) { + // Pagination token may be in format "MemberName.TokenName", extract just the token name + return outToken.contains(".") ? outToken.substring(outToken.lastIndexOf(".") + 1) : outToken; + } + + private String getNestedListMember(OperationShape op) { + // Check if the output has a nested list structure containing pagination tokens + // This pattern is used by CloudFront and potentially other services + String result = op.getOutput() + .flatMap(outputId -> context.getModel().getShape(outputId)) + .filter(shape -> shape instanceof StructureShape) + .map(shape -> (StructureShape) shape) + .flatMap(outputShape -> { + // Find a member that contains "list" in its name and has pagination tokens + return outputShape.getAllMembers().entrySet().stream() + .filter(entry -> entry.getKey().toLowerCase().contains("list")) + .filter(entry -> { + // Check if this member's target shape has pagination tokens + return context.getModel().getShape(entry.getValue().getTarget()) + .filter(targetShape -> targetShape instanceof StructureShape) + .map(targetShape -> (StructureShape) targetShape) + .map(targetStruct -> { + Set memberNames = targetStruct.getAllMembers().keySet(); + return memberNames.contains("NextMarker") || memberNames.contains("nextMarker") || + memberNames.contains("Marker") || memberNames.contains("marker") || + memberNames.contains("IsTruncated") || memberNames.contains("isTruncated"); + }) + .orElse(false); + }) + .map(entry -> entry.getKey()) + .findFirst(); + }) + .orElse(null); + + return result; + } + + private boolean isNumericToken(OperationShape op, String tokenName) { + // Check if the token is numeric by examining the shape type + return op.getOutput() + .flatMap(outputId -> context.getModel().getShape(outputId)) + .filter(shape -> shape instanceof StructureShape) + .map(shape -> (StructureShape) shape) + .flatMap(outputShape -> outputShape.getMember(tokenName)) + .flatMap(member -> context.getModel().getShape(member.getTarget())) + .map(targetShape -> targetShape instanceof IntegerShape || targetShape instanceof LongShape) + .orElse(false); + } } From cee39aee98ff2263e7afe4fe52ab1c68c3ea5b6b Mon Sep 17 00:00:00 2001 From: kai lin Date: Tue, 20 Jan 2026 15:54:53 -0500 Subject: [PATCH 22/46] added a patch to remove the unnessary version suffix strip --- .../templates/PaginationTraitsGenerator.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java index 9e89383d3deb..b981573c0fd4 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java @@ -181,21 +181,13 @@ private String getResultSuffix(String opName) { return "Response"; } - // For CloudFront, use the base operation name (without version suffix) for conflict detection - final String baseOpName; - if ("cloudfront".equals(c2jServiceName) && opName.endsWith("2020_05_31")) { - baseOpName = opName.substring(0, opName.length() - "2020_05_31".length()); - } else { - baseOpName = opName; - } - // Check for known SdkResult cases (where data model conflicts exist) Set allShapes = context.getModel().toSet(); boolean hasDataModelConflict = allShapes.stream() .anyMatch(shape -> { String shapeName = shape.getId().getName(); - // Check if there's a conflicting shape with the base name + "Result" - String candidateName = baseOpName + "Result"; + // Check if there's a conflicting shape with the operation name + "Result" + String candidateName = opName + "Result"; if (shapeName.equals(candidateName)) { // Found a shape with the same name - check if it's a data model (not an operation result) if (shape instanceof StructureShape) { From 043ddc7be2d5cb847e1306b07e4e3af1322fe762 Mon Sep 17 00:00:00 2001 From: kai lin Date: Tue, 20 Jan 2026 16:52:34 -0500 Subject: [PATCH 23/46] added a patch to refactor duplication logic to shapeutil, and changed the logic to be exactly like the legacy c2j formater --- .../generators/ShapeUtil.java | 70 +++++++++++++++++++ .../templates/PaginationTraitsGenerator.java | 57 ++------------- 2 files changed, 76 insertions(+), 51 deletions(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java index 0745a619a92d..2f0e245cdc28 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java @@ -22,4 +22,74 @@ public static Set getReferences(Model model, Shape root) { } return refs; } + + /** + * Determines the result suffix for an operation based on protocol and naming conflicts. + * Replicates C2J renameShape conflict detection logic. + * + * C2J logic: + * 1. Try "Result" first + * 2. If collision exists (direct name match OR Get/Set accessor conflict), try "SdkResult" + * 3. If still collision, try "CppSdkResult" + * + * @param model The Smithy model + * @param operation The operation shape + * @param c2jServiceName The C2J service name + * @return "Response" for EC2 protocol, "SdkResult" if naming conflict exists, otherwise "Result" + */ + public static String getResultSuffix(Model model, OperationShape operation, String c2jServiceName) { + // EC2 protocol services rename all Result shapes to Response + if ("ec2".equals(c2jServiceName)) { + return "Response"; + } + + String opName = operation.getId().getName(); + + // Get the operation's output shape to exclude from collision check + ShapeId outputShapeId = operation.getOutputShape(); + + // Try Result first, then SdkResult if collision + String[] suffixes = {"Result", "SdkResult", "CppSdkResult"}; + + for (String suffix : suffixes) { + String candidateName = opName + suffix; + if (!hasNamingConflict(model, candidateName, outputShapeId)) { + return suffix; + } + } + + // Fallback to CppSdkResult if all else fails + return "CppSdkResult"; + } + + /** + * Checks if a candidate name conflicts with existing shapes. + * Implements C2J collision detection: direct name match OR Get/Set accessor conflict. + * Excludes the operation's own output shape from collision check. + */ + private static boolean hasNamingConflict(Model model, String candidateName, ShapeId excludeShapeId) { + Set allShapes = model.toSet(); + + return allShapes.stream() + .anyMatch(shape -> { + String shapeName = shape.getId().getName(); + + // Skip the operation's own output shape by comparing names + if (excludeShapeId != null && shapeName.equals(excludeShapeId.getName())) { + return false; + } + + // Direct collision: candidateName equals existing shapeName + if (candidateName.equals(shapeName)) { + return true; + } + + // Get/Set accessor collision: candidateName equals "Get" + shapeName or "Set" + shapeName + if (candidateName.equals("Get" + shapeName) || candidateName.equals("Set" + shapeName)) { + return true; + } + + return false; + }); + } } \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java index b981573c0fd4..245f251c0944 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java @@ -12,6 +12,7 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriterDelegator; import com.amazonaws.util.awsclientsmithygenerator.generators.ServiceNameUtil; +import com.amazonaws.util.awsclientsmithygenerator.generators.ShapeUtil; import java.util.*; import java.util.Arrays; @@ -59,7 +60,7 @@ private void generateTraitsHeader(CppWriter writer, OperationData allShapes = context.getModel().toSet(); - boolean hasDataModelConflict = allShapes.stream() - .anyMatch(shape -> { - String shapeName = shape.getId().getName(); - // Check if there's a conflicting shape with the operation name + "Result" - String candidateName = opName + "Result"; - if (shapeName.equals(candidateName)) { - // Found a shape with the same name - check if it's a data model (not an operation result) - if (shape instanceof StructureShape) { - StructureShape structShape = (StructureShape) shape; - // Check if this is an operation result by looking for pagination-related patterns - Set memberNames = structShape.getAllMembers().keySet(); - - // Direct pagination tokens - boolean hasDirectPaginationTokens = memberNames.contains("NextToken") || memberNames.contains("nextToken") || - memberNames.contains("Marker") || memberNames.contains("marker") || - memberNames.contains("NextMarker") || memberNames.contains("nextMarker") || - memberNames.contains("IsTruncated") || memberNames.contains("isTruncated"); - - // Check for nested list structures (common in AWS APIs) - boolean hasNestedListStructure = memberNames.stream() - .anyMatch(memberName -> memberName.toLowerCase().contains("list")); - - // If it has direct pagination tokens or nested list structure, it's likely an operation result - boolean isOperationResult = hasDirectPaginationTokens || hasNestedListStructure; - - return !isOperationResult; - } - } - return false; - }); - - return hasDataModelConflict ? "SdkResult" : "Result"; - } - - private boolean isEc2Protocol() { - // EC2 protocol services rename all Result shapes to Response - // This matches the logic in Ec2CppClientGenerator.legacyPatchEc2Model - return "ec2".equals(c2jServiceName); + // TODO: Consider inlining this method since it's only called once and just delegates to ShapeUtil. + // Verify no other generators use this pattern before removing. + private String getResultSuffix(OperationShape op) { + return ShapeUtil.getResultSuffix(context.getModel(), op, c2jServiceName); } From 38300cf35ec8d6933b334a5146d11f7795212ec0 Mon Sep 17 00:00:00 2001 From: kai lin Date: Wed, 21 Jan 2026 14:32:48 -0500 Subject: [PATCH 24/46] added a patch to add codestar and hard coded maps --- .../generators/PaginationCodegenPlugin.java | 2 +- .../generators/ServiceNameUtil.java | 80 ++++++++++++++----- .../PaginationClientHeaderGenerator.java | 7 +- .../PaginationCompilationTestGenerator.java | 2 +- 4 files changed, 64 insertions(+), 27 deletions(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java index bd64ffd5c9a2..489392ea6849 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java @@ -41,7 +41,7 @@ public void execute(PluginContext context) { // Generate pagination files FeatureParser> parser = new FeatureParser<>(context, service, paginatedOps, "Pagination"); parser.run(featureParser -> { - String serviceName = featureParser.getServiceName(); + String serviceName = ServiceNameUtil.getServiceNameUpperCamel(featureParser.getService()); // Generate client pagination header featureParser.generateClientHeader( diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java index 2b54e2842316..b17cb94aebaa 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java @@ -14,18 +14,56 @@ public final class ServiceNameUtil { // Legacy service IDs that need special handling to match what the legacy c2j code generator produced // This logic is copied from C2jModelToGeneratorModelTransformer.convertMetadata() method - private static final Set LEGACY_SERVICE_IDS = Set.of( - "amp", "appintegrations", "amazonappintegrationservice", "billingconductor", "clouddirectory", "cloudfront", - "cloudsearch", "cloudsearchdomain", "codeartifact", "codestar-notifications", - "config", "databrew", "elasticache", "emr-containers", - "entitlement.marketplace", "events", "evidently", "forecast", "forecastquery", - "grafana", "importexport", "inspector", "lambda", "location", "lookoutvision", - "m2", "migrationhubstrategy", "mobile", "mobileanalytics", "mq", "nimble", - "opensearch", "rbin", "rds-data", "redshift-data", "resiliencehub", "rum", - "sagemaker-a2i-runtime", "sagemaker-edge", "schemas", "sdb", "transcribe", - "transcribe-streaming", "wisdom", "lex", "lexv2-runtime", "lexv2-models", - "marketplace-entitlement", "sagemaker-runtime", "awstransfer", "transcribestreaming", - "dynamodbstreams" + // Hardcoded mappings for legacy services where C2J used fullServiceName for file naming + // Maps serviceId (lowercase, sanitized) to the sanitized fullServiceName from C2J models + private static final Map LEGACY_FULL_SERVICE_NAME_MAP = Map.ofEntries( + Map.entry("amp", "PrometheusService"), + Map.entry("appintegrations", "AppIntegrationsService"), + Map.entry("billingconductor", "BillingConductor"), + Map.entry("chatbot", "chatbot"), + Map.entry("clouddirectory", "CloudDirectory"), + Map.entry("cloudfront", "CloudFront"), + Map.entry("cloudsearch", "CloudSearch"), + Map.entry("cloudsearchdomain", "CloudSearchDomain"), + Map.entry("codeartifact", "CodeArtifact"), + Map.entry("codestarnotifications", "CodeStarNotifications"), + Map.entry("configservice", "ConfigService"), + Map.entry("databrew", "GlueDataBrew"), + Map.entry("elasticache", "ElastiCache"), + Map.entry("emrcontainers", "EMRContainers"), + Map.entry("marketplaceentitlementservice", "MarketplaceEntitlementService"), + Map.entry("cloudwatchevents", "CloudWatchEvents"), + Map.entry("evidently", "CloudWatchEvidently"), + Map.entry("forecast", "ForecastService"), + Map.entry("forecastquery", "ForecastQueryService"), + Map.entry("grafana", "ManagedGrafana"), + Map.entry("importexport", "ImportExport"), + Map.entry("inspector", "Inspector"), + Map.entry("lambda", "Lambda"), + Map.entry("location", "LocationService"), + Map.entry("m2", "MainframeModernization"), + Map.entry("migrationhubstrategy", "MigrationHubStrategyRecommendations"), + Map.entry("mq", "MQ"), + Map.entry("opensearch", "OpenSearchService"), + Map.entry("rbin", "RecycleBin"), + Map.entry("rdsdata", "RDSDataService"), + Map.entry("redshiftdata", "RedshiftDataAPIService"), + Map.entry("resiliencehub", "ResilienceHub"), + Map.entry("rum", "CloudWatchRUM"), + Map.entry("lexruntimeservice", "LexRuntimeService"), + Map.entry("lexruntimev2", "LexRuntimeV2"), + Map.entry("lexmodelsv2", "LexModelBuildingV2"), + Map.entry("sagemakerruntime", "SageMakerRuntime"), + Map.entry("sagemakera2iruntime", "AugmentedAIRuntime"), + Map.entry("sagemakeredge", "SagemakerEdgeManager"), + Map.entry("schemas", "Schemas"), + Map.entry("simpledb", "SimpleDB"), + Map.entry("dynamodbstreams", "DynamoDBStreams"), + Map.entry("transcribe", "TranscribeService"), + Map.entry("transcribestreaming", "TranscribeStreamingService"), + Map.entry("transfer", "TransferFamily"), + Map.entry("wisdom", "ConnectWisdomService"), + Map.entry("marketplaceagreement", "MarketplaceAgreementService") ); // TODO: Remove hardcoded mappings once Smithy models include serviceAbbreviation trait @@ -58,22 +96,20 @@ public static String getServiceName(ServiceShape service) { .map(ServiceTrait::getSdkId) .orElse(service.getId().getName()); - // Check hardcoded mappings first String sanitized = sanitizeServiceAbbreviation(serviceId); + + // Check legacy fullServiceName mappings first + String legacyName = LEGACY_FULL_SERVICE_NAME_MAP.get(sanitized.toLowerCase()); + if (legacyName != null) { + return legacyName; + } + + // Check hardcoded mappings String mapped = SMITHY_TO_C2J_NAMESPACE.get(sanitized.toLowerCase()); if (mapped != null) { return mapped; } - if (LEGACY_SERVICE_IDS.contains(serviceId.toLowerCase())) { - String title = service.getTrait(TitleTrait.class) - .map(TitleTrait::getValue) - .orElse(null); - if (title != null) { - return sanitizeServiceAbbreviation(title); - } - } - return sanitized; } diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java index 4e8d04768310..7c9235fa5b61 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java @@ -43,8 +43,8 @@ public void render(CppWriter writer) { } private void renderIncludes(CppWriter writer, String serviceName, String c2jServiceName) { - String capitalizedServiceName = ServiceNameUtil.getServiceNameUpperCamel(service); - writer.writeInclude("aws/" + c2jServiceName + "/" + capitalizedServiceName + "Client.h"); + String classPrefix = ServiceNameUtil.getServiceNameUpperCamel(service); + writer.writeInclude("aws/" + c2jServiceName + "/" + classPrefix + "Client.h"); writer.writeInclude("aws/core/utils/pagination/Paginator.h"); for (OperationData data : paginatedOps) { @@ -55,6 +55,7 @@ private void renderIncludes(CppWriter writer, String serviceName, String c2jServ } private void renderNamespaces(CppWriter writer, String serviceName) { + String classPrefix = ServiceNameUtil.getServiceNameUpperCamel(service); writer.writeNamespaceOpen("Aws"); writer.writeNamespaceOpen(serviceName); writer.write(""); @@ -63,7 +64,7 @@ private void renderNamespaces(CppWriter writer, String serviceName) { String opName = data.getOperation().getId().getName(); String methodName = ServiceNameUtil.getClientMethodName(opName, c2jServiceName); writer.write("using $LPaginator = Aws::Utils::Pagination::PagePaginator<$LClient, Model::$LRequest, Pagination::$LPaginationTraits>;", - opName, ServiceNameUtil.getServiceNameUpperCamel(service), methodName, opName); + opName, classPrefix, methodName, opName); } writer.write(""); diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java index 69c7ee22dc1c..0bcf0ab3f4b2 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java @@ -74,7 +74,7 @@ private void writeIncludes(CppWriter writer) { for (OperationData paginationData : allPaginatedOps) { ServiceShape service = paginationData.getService(); - String serviceName = ServiceNameUtil.getServiceName(service); + String serviceName = ServiceNameUtil.getServiceNameUpperCamel(service); String c2jServiceName = ServiceNameUtil.getC2jServiceName(service, c2jMap); // Collect unique client headers From 46406de690d68705c29760a71644969af98b71f8 Mon Sep 17 00:00:00 2001 From: kai lin Date: Wed, 21 Jan 2026 14:41:46 -0500 Subject: [PATCH 25/46] added a patch to add deadline --- .../awsclientsmithygenerator/generators/ServiceNameUtil.java | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java index b17cb94aebaa..19603ebaf058 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java @@ -29,6 +29,7 @@ public final class ServiceNameUtil { Map.entry("codestarnotifications", "CodeStarNotifications"), Map.entry("configservice", "ConfigService"), Map.entry("databrew", "GlueDataBrew"), + Map.entry("deadline", "deadline"), Map.entry("elasticache", "ElastiCache"), Map.entry("emrcontainers", "EMRContainers"), Map.entry("marketplaceentitlementservice", "MarketplaceEntitlementService"), From 27815768185252c01cf1c860f494bd0354433d3d Mon Sep 17 00:00:00 2001 From: kai lin Date: Wed, 21 Jan 2026 16:16:26 -0500 Subject: [PATCH 26/46] added a patch to add transfer to abbreivation list and fix the servicename reshape priority --- .../generators/ServiceNameUtil.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java index 19603ebaf058..09d15c972d45 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java @@ -89,7 +89,8 @@ public final class ServiceNameUtil { Map.entry("savingsplans", "SavingsPlans"), Map.entry("servicecatalogappregistry", "AppRegistry"), Map.entry("sesv2", "SESV2"), - Map.entry("synthetics", "Synthetics") + Map.entry("synthetics", "Synthetics"), + Map.entry("transfer", "Transfer") ); public static String getServiceName(ServiceShape service) { @@ -99,18 +100,18 @@ public static String getServiceName(ServiceShape service) { String sanitized = sanitizeServiceAbbreviation(serviceId); - // Check legacy fullServiceName mappings first - String legacyName = LEGACY_FULL_SERVICE_NAME_MAP.get(sanitized.toLowerCase()); - if (legacyName != null) { - return legacyName; - } - - // Check hardcoded mappings + // Check serviceAbbreviation mappings first (highest priority in C2J) String mapped = SMITHY_TO_C2J_NAMESPACE.get(sanitized.toLowerCase()); if (mapped != null) { return mapped; } + // Check legacy fullServiceName mappings (fallback when serviceAbbreviation missing) + String legacyName = LEGACY_FULL_SERVICE_NAME_MAP.get(sanitized.toLowerCase()); + if (legacyName != null) { + return legacyName; + } + return sanitized; } From c9a3b3d0b0073f1d0f6be9e30f40a076044841c8 Mon Sep 17 00:00:00 2001 From: kai lin Date: Wed, 21 Jan 2026 17:57:42 -0500 Subject: [PATCH 27/46] added a patch to ecr to fix GetLifecyclePolicyPreviewSdkResult.h. changed shapeutil logic to correctly use the legacy get/set collision rule --- .../generators/ShapeUtil.java | 107 +++++++++++------- 1 file changed, 67 insertions(+), 40 deletions(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java index 2f0e245cdc28..c1dd21e47a4d 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java @@ -6,11 +6,12 @@ import software.amazon.smithy.model.Model; import software.amazon.smithy.model.shapes.*; -import java.util.HashSet; -import java.util.Set; +import java.util.*; public class ShapeUtil { + private static final List RESULT_SUFFIXES = List.of("Result", "SdkResult", "CppSdkResult"); + /** * Returns all shapes referenced by a root shape, recursively. */ @@ -43,53 +44,79 @@ public static String getResultSuffix(Model model, OperationShape operation, Stri return "Response"; } - String opName = operation.getId().getName(); + String baseName = operation.getId().getName(); + Set allShapeNames = getAllShapeNames(model); - // Get the operation's output shape to exclude from collision check - ShapeId outputShapeId = operation.getOutputShape(); + // Output shape name (used for legacy early-accept behavior) + String outputShapeName = operation.getOutput().isPresent() + ? operation.getOutputShape().getName() + : null; - // Try Result first, then SdkResult if collision - String[] suffixes = {"Result", "SdkResult", "CppSdkResult"}; + // For closer parity with the legacy Get/Set collision rule + Set outputMemberNames = getOutputMemberNames(model, operation); - for (String suffix : suffixes) { - String candidateName = opName + suffix; - if (!hasNamingConflict(model, candidateName, outputShapeId)) { + for (String suffix : RESULT_SUFFIXES) { + String candidate = baseName + suffix; + + // Legacy parity: if the operation's output shape is already named exactly candidate, + // then legacy renameShape() would return immediately (no conflict handling). + if (outputShapeName != null && candidate.equals(outputShapeName)) { return suffix; } + + // Legacy: otherwise, direct collision with any existing shape name is a conflict + if (allShapeNames.contains(candidate)) { + continue; + } + + // Closer parity with legacy intent (member-gated Get/Set collisions) + if (hasGetSetCollision(candidate, allShapeNames, outputMemberNames)) { + continue; + } + + return suffix; } - // Fallback to CppSdkResult if all else fails - return "CppSdkResult"; + // Legacy would throw if no suffix is available; returning CppSdkResult silently can hide bugs + throw new IllegalStateException("Unhandled result shape name conflict for operation: " + baseName); } - /** - * Checks if a candidate name conflicts with existing shapes. - * Implements C2J collision detection: direct name match OR Get/Set accessor conflict. - * Excludes the operation's own output shape from collision check. - */ - private static boolean hasNamingConflict(Model model, String candidateName, ShapeId excludeShapeId) { - Set allShapes = model.toSet(); + private static Set getAllShapeNames(Model model) { + Set names = new HashSet<>(); + model.shapes().forEach(s -> names.add(s.getId().getName())); + return names; + } + + private static Set getOutputMemberNames(Model model, OperationShape op) { + // If no output or not a structure, return empty + if (!op.getOutput().isPresent()) { + return Collections.emptySet(); + } + ShapeId outputId = op.getOutputShape(); + Shape output = model.expectShape(outputId); + if (!output.isStructureShape()) { + return Collections.emptySet(); + } + StructureShape struct = output.asStructureShape().get(); + return new HashSet<>(struct.getAllMembers().keySet()); + } + + private static boolean hasGetSetCollision(String candidate, + Set allShapeNames, + Set outputMemberNames) { + if (outputMemberNames.isEmpty()) { + return false; + } - return allShapes.stream() - .anyMatch(shape -> { - String shapeName = shape.getId().getName(); - - // Skip the operation's own output shape by comparing names - if (excludeShapeId != null && shapeName.equals(excludeShapeId.getName())) { - return false; - } - - // Direct collision: candidateName equals existing shapeName - if (candidateName.equals(shapeName)) { - return true; - } - - // Get/Set accessor collision: candidateName equals "Get" + shapeName or "Set" + shapeName - if (candidateName.equals("Get" + shapeName) || candidateName.equals("Set" + shapeName)) { - return true; - } - - return false; - }); + // Legacy logic: only treat GetX/SetX as conflict if X is both a known shape name and a member name + for (String shapeName : allShapeNames) { + if (!outputMemberNames.contains(shapeName)) { + continue; + } + if (candidate.equals("Get" + shapeName) || candidate.equals("Set" + shapeName)) { + return true; + } + } + return false; } } \ No newline at end of file From 1b0e434784eccd50a33b3c4ee57092cf505d30bb Mon Sep 17 00:00:00 2001 From: kai lin Date: Wed, 21 Jan 2026 18:57:11 -0500 Subject: [PATCH 28/46] added a patch for elasticache Fix pagination traits generator for nested tokens andle explicit nested tokens like "EngineDefaults.Marker" correctly --- .../templates/PaginationTraitsGenerator.java | 138 +++++++++++------- 1 file changed, 89 insertions(+), 49 deletions(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java index 245f251c0944..229cb50840f8 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java @@ -97,14 +97,42 @@ private void generateTraitsHeader(CppWriter writer, OperationData { if (trait.getOutputToken().isPresent()) { String outToken = trait.getOutputToken().get(); - String nestedListMember = getNestedListMember(op); - String tokenName = extractTokenName(outToken); - if (nestedListMember != null) { - writer.write(" return !result.Get$L().Get$L().empty();", capitalize(nestedListMember), capitalize(tokenName)); - } else if (isNumericToken(op, outToken)) { - writer.write(" return result.Get$L() != 0;", capitalize(outToken)); - } else { - writer.write(" return !result.Get$L().empty();", capitalize(outToken)); + + // TODO: Refactor HasMoreResults and SetNextRequest to share common token resolution logic + // Both methods duplicate the same pattern matching (explicit nesting, top-level, wrapper) + // Pattern A: Explicit nested token like "EngineDefaults.Marker" + if (outToken.contains(".")) { + String[] parts = outToken.split("\\.", 2); + String memberName = parts[0]; + String nestedTokenName = parts[1]; + if (isNumericToken(op, memberName, nestedTokenName)) { + writer.write(" return result.Get$L().Get$L() != 0;", capitalize(memberName), capitalize(nestedTokenName)); + } else { + writer.write(" return !result.Get$L().Get$L().empty();", capitalize(memberName), capitalize(nestedTokenName)); + } + } + // Pattern B: Check if token is on top-level output + else if (hasTopLevelMember(op, outToken)) { + if (isNumericToken(op, null, outToken)) { + writer.write(" return result.Get$L() != 0;", capitalize(outToken)); + } else { + writer.write(" return !result.Get$L().empty();", capitalize(outToken)); + } + } + // Pattern C: Find wrapper member containing the token + else { + String wrapperMember = findWrapperMemberContainingToken(op, outToken); + if (wrapperMember != null) { + if (isNumericToken(op, wrapperMember, outToken)) { + writer.write(" return result.Get$L().Get$L() != 0;", capitalize(wrapperMember), capitalize(outToken)); + } else { + writer.write(" return !result.Get$L().Get$L().empty();", capitalize(wrapperMember), capitalize(outToken)); + } + } else if (hasTopLevelMember(op, "IsTruncated")) { + writer.write(" return result.GetIsTruncated();"); + } else { + writer.write(" return false;"); + } } } else { // TODO: Check how legacy C2J code generation handles service-level pagination @@ -114,7 +142,7 @@ private void generateTraitsHeader(CppWriter writer, OperationData context.getModel().getShape(outputId)) - .filter(shape -> shape instanceof StructureShape) - .map(shape -> (StructureShape) shape) - .flatMap(outputShape -> { - // Find a member that contains "list" in its name and has pagination tokens - return outputShape.getAllMembers().entrySet().stream() - .filter(entry -> entry.getKey().toLowerCase().contains("list")) - .filter(entry -> { - // Check if this member's target shape has pagination tokens - return context.getModel().getShape(entry.getValue().getTarget()) - .filter(targetShape -> targetShape instanceof StructureShape) - .map(targetShape -> (StructureShape) targetShape) - .map(targetStruct -> { - Set memberNames = targetStruct.getAllMembers().keySet(); - return memberNames.contains("NextMarker") || memberNames.contains("nextMarker") || - memberNames.contains("Marker") || memberNames.contains("marker") || - memberNames.contains("IsTruncated") || memberNames.contains("isTruncated"); - }) - .orElse(false); - }) - .map(entry -> entry.getKey()) - .findFirst(); - }) + .flatMap(shape -> shape.asStructureShape()) + .flatMap(outputShape -> + outputShape.getAllMembers().entrySet().stream() + .filter(entry -> context.getModel().getShape(entry.getValue().getTarget()) + .flatMap(t -> t.asStructureShape()) + .map(s -> s.getAllMembers().containsKey(tokenName)) + .orElse(false)) + .map(Map.Entry::getKey) + .findFirst() + ) .orElse(null); - - return result; } - private boolean isNumericToken(OperationShape op, String tokenName) { - // Check if the token is numeric by examining the shape type + private boolean hasTopLevelMember(OperationShape op, String memberName) { return op.getOutput() .flatMap(outputId -> context.getModel().getShape(outputId)) - .filter(shape -> shape instanceof StructureShape) - .map(shape -> (StructureShape) shape) - .flatMap(outputShape -> outputShape.getMember(tokenName)) - .flatMap(member -> context.getModel().getShape(member.getTarget())) - .map(targetShape -> targetShape instanceof IntegerShape || targetShape instanceof LongShape) + .flatMap(shape -> shape.asStructureShape()) + .map(outputShape -> outputShape.getAllMembers().containsKey(memberName)) .orElse(false); } + + private boolean isNumericToken(OperationShape op, String wrapperMember, String tokenName) { + Optional tokenShape = + op.getOutput() + .flatMap(outputId -> context.getModel().getShape(outputId)) + .flatMap(s -> s.asStructureShape()) + .flatMap(out -> { + if (wrapperMember == null) { + return out.getMember(tokenName); + } + return out.getMember(wrapperMember) + .flatMap(m -> context.getModel().getShape(m.getTarget())) + .flatMap(t -> t.asStructureShape()) + .flatMap(w -> w.getMember(tokenName)); + }) + .flatMap(member -> context.getModel().getShape(member.getTarget())); + + return tokenShape.map(ts -> ts instanceof IntegerShape || ts instanceof LongShape).orElse(false); + } } From d6ca368f5ae7d534abf9196ad49ea29a1a3b04c8 Mon Sep 17 00:00:00 2001 From: kai lin Date: Wed, 21 Jan 2026 20:31:06 -0500 Subject: [PATCH 29/46] added a patch for lexv2-models. abbreviation and servicename mismatch --- .../awsclientsmithygenerator/generators/ServiceNameUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java index 09d15c972d45..eabe01e6763e 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java @@ -53,7 +53,7 @@ public final class ServiceNameUtil { Map.entry("rum", "CloudWatchRUM"), Map.entry("lexruntimeservice", "LexRuntimeService"), Map.entry("lexruntimev2", "LexRuntimeV2"), - Map.entry("lexmodelsv2", "LexModelBuildingV2"), + Map.entry("lexmodelsv2", "LexModelsV2"), Map.entry("sagemakerruntime", "SageMakerRuntime"), Map.entry("sagemakera2iruntime", "AugmentedAIRuntime"), Map.entry("sagemakeredge", "SagemakerEdgeManager"), From 9abe05be9e8186f38342851444b17f348cf0d1f4 Mon Sep 17 00:00:00 2001 From: kai lin Date: Thu, 22 Jan 2026 10:50:46 -0500 Subject: [PATCH 30/46] added a patch for medialive Backward compatibility map for operations that must use "SdkResult" suffix. --- .../generators/ShapeUtil.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java index c1dd21e47a4d..6574814a8f64 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java @@ -12,6 +12,38 @@ public class ShapeUtil { private static final List RESULT_SUFFIXES = List.of("Result", "SdkResult", "CppSdkResult"); + /** + * Backward compatibility map for operations that must use "SdkResult" suffix. + * + * Background: + * The C2J code generator's renameShape() tries suffixes in order: Result -> SdkResult -> CppSdkResult. + * It picks the first suffix that doesn't collide with existing shape names in the model. + * + * Problem: + * Some legacy C2J models (e.g., medialive-2017-10-14.normal.json) defined shapes like: + * - ListNodesResult (a domain shape) + * - ListNodesResponse (the operation output shape) + * + * When the C2J generator tried to create the SDK wrapper for ListNodes operation: + * 1. Tried "ListNodesResult" -> COLLISION with existing shape + * 2. Fell back to "ListNodesSdkResult" -> No collision, used this + * + * The Smithy models are cleaner and don't have these collisions, but we must preserve + * the "SdkResult" suffix for these operations to maintain backward compatibility with + * existing C2J-generated code. + * + * Map format: service-name -> Set of operation names requiring "SdkResult" + * + * Example: + * medialive C2J model had both ListNodesResult and ListNodesResponse shapes, + * forcing ListNodesSdkResult. Smithy model only has ListNodesResponse, but we + * preserve SdkResult to avoid breaking changes. + * + */ + private static final Map> LEGACY_SDK_RESULT_OPERATIONS = Map.of( + "medialive", Set.of("ListChannelPlacementGroups", "ListClusters", "ListNetworks", "ListNodes") + ); + /** * Returns all shapes referenced by a root shape, recursively. */ @@ -44,6 +76,12 @@ public static String getResultSuffix(Model model, OperationShape operation, Stri return "Response"; } + // C2J backward compatibility: preserve SdkResult for operations that had collisions in legacy models + Set legacyOps = LEGACY_SDK_RESULT_OPERATIONS.get(c2jServiceName); + if (legacyOps != null && legacyOps.contains(operation.getId().getName())) { + return "SdkResult"; + } + String baseName = operation.getId().getName(); Set allShapeNames = getAllShapeNames(model); From cde65e02950beef8375061ed9a7202d55d57e955 Mon Sep 17 00:00:00 2001 From: kai lin Date: Thu, 22 Jan 2026 11:40:11 -0500 Subject: [PATCH 31/46] added a patch for s3 list parts where S3's ListParts operation has NextPartNumberMarker as integer in C2J but string in Smithy. --- .../pagination/ListPartsPaginationTraits.h | 2 +- .../generators/ShapeUtil.java | 35 +++++++++++++++++++ .../templates/PaginationTraitsGenerator.java | 5 +++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h index 2a847a744eca..dc6a20a510d9 100644 --- a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h @@ -21,7 +21,7 @@ struct ListPartsPaginationTraits { static OutcomeType Invoke(ClientType& client, const RequestType& request) { return client.ListParts(request); } - static bool HasMoreResults(const ResultType& result) { return !result.GetNextPartNumberMarker().empty(); } + static bool HasMoreResults(const ResultType& result) { return result.GetNextPartNumberMarker() != 0; } static void SetNextRequest(const ResultType& result, RequestType& request) { request.SetPartNumberMarker(result.GetNextPartNumberMarker()); diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java index 6574814a8f64..404a542b304b 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java @@ -44,6 +44,24 @@ public class ShapeUtil { "medialive", Set.of("ListChannelPlacementGroups", "ListClusters", "ListNetworks", "ListNodes") ); + /** + * C2J/Smithy model mismatches: pagination tokens that are integers in C2J but strings in Smithy. + * + * Background: + * Some services have pagination tokens that were modeled as integers in C2J but changed to + * strings in Smithy models. The C2J-generated code uses int types, so pagination traits must + * use `!= 0` checks instead of `.empty()` checks. + * + * Map format: service-name -> Map of operation-name -> token-name + * + * Example: + * S3's ListParts operation has NextPartNumberMarker as integer in C2J but string in Smithy. + */ + private static final Map>> NUMERIC_TOKEN_OVERRIDES = Map.of( + "s3", Map.of("ListParts", Set.of("NextPartNumberMarker")), + "s3-crt", Map.of("ListParts", Set.of("NextPartNumberMarker")) + ); + /** * Returns all shapes referenced by a root shape, recursively. */ @@ -56,6 +74,23 @@ public static Set getReferences(Model model, Shape root) { return refs; } + /** + * Checks if a pagination token should be treated as numeric due to C2J/Smithy model mismatch. + * + * @param c2jServiceName The C2J service name + * @param operationName The operation name + * @param tokenName The pagination token name + * @return true if token is numeric in C2J but string in Smithy + */ + public static boolean isNumericTokenOverride(String c2jServiceName, String operationName, String tokenName) { + Map> serviceOverrides = NUMERIC_TOKEN_OVERRIDES.get(c2jServiceName); + if (serviceOverrides == null) { + return false; + } + Set tokens = serviceOverrides.get(operationName); + return tokens != null && tokens.contains(tokenName); + } + /** * Determines the result suffix for an operation based on protocol and naming conflicts. * Replicates C2J renameShape conflict detection logic. diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java index 229cb50840f8..f91c2d3abf8f 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java @@ -275,6 +275,11 @@ private boolean hasTopLevelMember(OperationShape op, String memberName) { } private boolean isNumericToken(OperationShape op, String wrapperMember, String tokenName) { + // Check for C2J/Smithy model mismatch overrides first + if (ShapeUtil.isNumericTokenOverride(c2jServiceName, op.getId().getName(), tokenName)) { + return true; + } + Optional tokenShape = op.getOutput() .flatMap(outputId -> context.getModel().getShape(outputId)) From d107a1e09f23cdc16bb4032a1131142565a24dec Mon Sep 17 00:00:00 2001 From: kai lin Date: Thu, 22 Jan 2026 14:15:26 -0500 Subject: [PATCH 32/46] added integration tests for s3,ec2,dynamodb --- .../model/pagination/ScanPaginationTraits.h | 31 +++ ...DescribeSpotPriceHistoryPaginationTraits.h | 31 +++ .../DynamoDBPaginationCompilationTests.cpp | 27 +++ .../EC2PaginationCompilationTests.cpp | 184 +++++++++++++++ .../ScanPaginationIntegrationTest.cpp | 209 ++++++++++++++++++ .../EC2PaginationIntegrationTest.cpp | 152 +++++++++++++ ...ListObjectsV2PaginationIntegrationTest.cpp | 175 +++++++++++++++ 7 files changed, 809 insertions(+) create mode 100644 generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/model/pagination/ScanPaginationTraits.h create mode 100644 generated/src/aws-cpp-sdk-ec2/include/aws/ec2/model/pagination/DescribeSpotPriceHistoryPaginationTraits.h create mode 100644 generated/tests/dynamodb-gen-tests/DynamoDBPaginationCompilationTests.cpp create mode 100644 generated/tests/ec2-gen-tests/EC2PaginationCompilationTests.cpp create mode 100644 tests/aws-cpp-sdk-dynamodb-integration-tests/ScanPaginationIntegrationTest.cpp create mode 100644 tests/aws-cpp-sdk-ec2-integration-tests/EC2PaginationIntegrationTest.cpp create mode 100644 tests/aws-cpp-sdk-s3-integration-tests/ListObjectsV2PaginationIntegrationTest.cpp diff --git a/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/model/pagination/ScanPaginationTraits.h b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/model/pagination/ScanPaginationTraits.h new file mode 100644 index 000000000000..0cd157c097ec --- /dev/null +++ b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/model/pagination/ScanPaginationTraits.h @@ -0,0 +1,31 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once +#include +#include +#include +#include + +namespace Aws { +namespace DynamoDB { +namespace Pagination { + +struct ScanPaginationTraits { + using RequestType = Model::ScanRequest; + using ResultType = Model::ScanResult; + using OutcomeType = Model::ScanOutcome; + using ClientType = DynamoDBClient; + + static OutcomeType Invoke(ClientType& client, const RequestType& request) { return client.Scan(request); } + + static bool HasMoreResults(const ResultType& result) { return !result.GetLastEvaluatedKey().empty(); } + + static void SetNextRequest(const ResultType& result, RequestType& request) { request.SetExclusiveStartKey(result.GetLastEvaluatedKey()); } +}; + +} // namespace Pagination +} // namespace DynamoDB +} // namespace Aws diff --git a/generated/src/aws-cpp-sdk-ec2/include/aws/ec2/model/pagination/DescribeSpotPriceHistoryPaginationTraits.h b/generated/src/aws-cpp-sdk-ec2/include/aws/ec2/model/pagination/DescribeSpotPriceHistoryPaginationTraits.h new file mode 100644 index 000000000000..871357593c24 --- /dev/null +++ b/generated/src/aws-cpp-sdk-ec2/include/aws/ec2/model/pagination/DescribeSpotPriceHistoryPaginationTraits.h @@ -0,0 +1,31 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once +#include +#include +#include +#include + +namespace Aws { +namespace EC2 { +namespace Pagination { + +struct DescribeSpotPriceHistoryPaginationTraits { + using RequestType = Model::DescribeSpotPriceHistoryRequest; + using ResultType = Model::DescribeSpotPriceHistoryResponse; + using OutcomeType = Model::DescribeSpotPriceHistoryOutcome; + using ClientType = EC2Client; + + static OutcomeType Invoke(ClientType& client, const RequestType& request) { return client.DescribeSpotPriceHistory(request); } + + static bool HasMoreResults(const ResultType& result) { return !result.GetNextToken().empty(); } + + static void SetNextRequest(const ResultType& result, RequestType& request) { request.SetNextToken(result.GetNextToken()); } +}; + +} // namespace Pagination +} // namespace EC2 +} // namespace Aws diff --git a/generated/tests/dynamodb-gen-tests/DynamoDBPaginationCompilationTests.cpp b/generated/tests/dynamodb-gen-tests/DynamoDBPaginationCompilationTests.cpp new file mode 100644 index 000000000000..c4e9ee0bb112 --- /dev/null +++ b/generated/tests/dynamodb-gen-tests/DynamoDBPaginationCompilationTests.cpp @@ -0,0 +1,27 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +// Header compilation test for DynamoDB pagination headers +// This test ensures all generated pagination headers compile successfully + +#include +#include +#include +#include +#include +#include +#include + +#include + +class DynamoDBPaginationCompilationTest : public Aws::Testing::AwsCppSdkGTestSuite +{ +}; + +TEST_F(DynamoDBPaginationCompilationTest, DynamoDBPaginationHeadersCompile) +{ + // Test passes if compilation succeeds + SUCCEED(); +} diff --git a/generated/tests/ec2-gen-tests/EC2PaginationCompilationTests.cpp b/generated/tests/ec2-gen-tests/EC2PaginationCompilationTests.cpp new file mode 100644 index 000000000000..9ec13d3291ac --- /dev/null +++ b/generated/tests/ec2-gen-tests/EC2PaginationCompilationTests.cpp @@ -0,0 +1,184 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +// Header compilation test for EC2 pagination headers +// This test ensures all generated pagination headers compile successfully + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +class EC2PaginationCompilationTest : public Aws::Testing::AwsCppSdkGTestSuite +{ +}; + +TEST_F(EC2PaginationCompilationTest, EC2PaginationHeadersCompile) +{ + // Test passes if compilation succeeds + SUCCEED(); +} diff --git a/tests/aws-cpp-sdk-dynamodb-integration-tests/ScanPaginationIntegrationTest.cpp b/tests/aws-cpp-sdk-dynamodb-integration-tests/ScanPaginationIntegrationTest.cpp new file mode 100644 index 000000000000..d43c8f8a8aa6 --- /dev/null +++ b/tests/aws-cpp-sdk-dynamodb-integration-tests/ScanPaginationIntegrationTest.cpp @@ -0,0 +1,209 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace Aws; +using namespace Aws::DynamoDB; +using namespace Aws::DynamoDB::Model; + +namespace { + static const char* ALLOCATION_TAG = "ScanPaginationTest"; + const size_t ITEM_COUNT = 19; + const Aws::String HASH_KEY_NAME = "id"; + const Aws::String ATTRIBUTE_FOO = "attribute_foo"; +} + +class ScanPaginationTest : public Aws::Testing::AwsCppSdkGTestSuite { +protected: + std::shared_ptr dynamoClient; + Aws::String tableName; + + void SetUp() override { + Aws::SDKOptions options; + Aws::InitAPI(options); + + dynamoClient = Aws::MakeShared(ALLOCATION_TAG); + tableName = CalculateTableName("scan-paginator-test"); + + CreateTable(); + PutTestData(); + } + + void TearDown() override { + DeleteTableRequest deleteRequest; + deleteRequest.SetTableName(tableName); + dynamoClient->DeleteTable(deleteRequest); + + Aws::SDKOptions options; + Aws::ShutdownAPI(options); + } + + Aws::String CalculateTableName(const Aws::String& tablePrefix) { + return Aws::Testing::GetAwsResourcePrefix() + tablePrefix; + } + + void CreateTable() { + CreateTableRequest createRequest; + createRequest.SetTableName(tableName); + + KeySchemaElement keySchema; + keySchema.SetKeyType(KeyType::HASH); + keySchema.SetAttributeName(HASH_KEY_NAME); + createRequest.AddKeySchema(keySchema); + + AttributeDefinition attrDef; + attrDef.SetAttributeType(ScalarAttributeType::N); + attrDef.SetAttributeName(HASH_KEY_NAME); + createRequest.AddAttributeDefinitions(attrDef); + + ProvisionedThroughput throughput; + throughput.SetReadCapacityUnits(5); + throughput.SetWriteCapacityUnits(5); + createRequest.SetProvisionedThroughput(throughput); + + auto outcome = dynamoClient->CreateTable(createRequest); + ASSERT_TRUE(outcome.IsSuccess()); + + // Wait for table to be active (simplified) + std::this_thread::sleep_for(std::chrono::seconds(10)); + } + + void PutTestData() { + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<> dis(0, ITEM_COUNT - 1); + + for (size_t i = 0; i < ITEM_COUNT; ++i) { + PutItemRequest putRequest; + putRequest.SetTableName(tableName); + + Aws::Map item; + item[HASH_KEY_NAME] = AttributeValue().SetN(std::to_string(i)); + item[ATTRIBUTE_FOO] = AttributeValue().SetN(std::to_string(dis(gen))); + + putRequest.SetItem(item); + auto outcome = dynamoClient->PutItem(putRequest); + ASSERT_TRUE(outcome.IsSuccess()); + } + } +}; + +TEST_F(ScanPaginationTest, TestMultipleIterationOnResponses) { + ScanRequest request; + request.SetTableName(tableName); + request.SetConsistentRead(true); + request.SetLimit(2); + + size_t count = 0; + auto outcome = dynamoClient->Scan(request); + + // First iteration + while (outcome.IsSuccess()) { + const auto& result = outcome.GetResult(); + count += result.GetCount(); + + if (!Aws::DynamoDB::Pagination::ScanPaginationTraits::HasMoreResults(result)) { + break; + } + + Aws::DynamoDB::Pagination::ScanPaginationTraits::SetNextRequest(result, request); + outcome = dynamoClient->Scan(request); + } + + EXPECT_EQ(ITEM_COUNT, count); + + // Reset for second iteration + request = ScanRequest(); + request.SetTableName(tableName); + request.SetConsistentRead(true); + request.SetLimit(2); + + count = 0; + outcome = dynamoClient->Scan(request); + + // Second iteration + while (outcome.IsSuccess()) { + const auto& result = outcome.GetResult(); + count += result.GetCount(); + + if (!Aws::DynamoDB::Pagination::ScanPaginationTraits::HasMoreResults(result)) { + break; + } + + Aws::DynamoDB::Pagination::ScanPaginationTraits::SetNextRequest(result, request); + outcome = dynamoClient->Scan(request); + } + + EXPECT_EQ(ITEM_COUNT, count); +} + +TEST_F(ScanPaginationTest, TestPaginationWithLimit) { + ScanRequest request; + request.SetTableName(tableName); + request.SetConsistentRead(true); + request.SetLimit(3); + + size_t totalItems = 0; + size_t pageCount = 0; + auto outcome = dynamoClient->Scan(request); + + while (outcome.IsSuccess()) { + const auto& result = outcome.GetResult(); + totalItems += result.GetCount(); + pageCount++; + + if (!Aws::DynamoDB::Pagination::ScanPaginationTraits::HasMoreResults(result)) { + break; + } + + Aws::DynamoDB::Pagination::ScanPaginationTraits::SetNextRequest(result, request); + outcome = dynamoClient->Scan(request); + } + + EXPECT_EQ(ITEM_COUNT, totalItems); + EXPECT_GT(pageCount, 1u); // Should have multiple pages with limit=3 +} + +TEST_F(ScanPaginationTest, TestManualPaginationWithExclusiveStartKey) { + ScanRequest request; + request.SetTableName(tableName); + request.SetConsistentRead(true); + request.SetLimit(5); + + Aws::Vector> allItems; + + do { + auto outcome = dynamoClient->Scan(request); + ASSERT_TRUE(outcome.IsSuccess()); + + const auto& result = outcome.GetResult(); + for (const auto& item : result.GetItems()) { + allItems.push_back(item); + } + + if (!result.GetLastEvaluatedKey().empty()) { + request.SetExclusiveStartKey(result.GetLastEvaluatedKey()); + } else { + break; + } + } while (true); + + EXPECT_EQ(ITEM_COUNT, allItems.size()); +} \ No newline at end of file diff --git a/tests/aws-cpp-sdk-ec2-integration-tests/EC2PaginationIntegrationTest.cpp b/tests/aws-cpp-sdk-ec2-integration-tests/EC2PaginationIntegrationTest.cpp new file mode 100644 index 000000000000..ed129d874a9e --- /dev/null +++ b/tests/aws-cpp-sdk-ec2-integration-tests/EC2PaginationIntegrationTest.cpp @@ -0,0 +1,152 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace Aws; +using namespace Aws::EC2; +using namespace Aws::EC2::Model; + +namespace { + static const char* ALLOCATION_TAG = "EC2PaginationTest"; +} + +class EC2PaginationTest : public Aws::Testing::AwsCppSdkGTestSuite { +protected: + std::shared_ptr ec2Client; + + void SetUp() override { + Aws::SDKOptions options; + Aws::InitAPI(options); + + Aws::Client::ClientConfiguration config; + config.region = "us-east-1"; + ec2Client = Aws::MakeShared(ALLOCATION_TAG, config); + } + + void TearDown() override { + Aws::SDKOptions options; + Aws::ShutdownAPI(options); + } +}; + +TEST_F(EC2PaginationTest, TestSpotPriceHistoryPagination) { + DescribeSpotPriceHistoryRequest request; + request.SetAvailabilityZone("us-east-1a"); + request.AddProductDescriptions("Linux/UNIX (Amazon VPC)"); + request.AddInstanceTypes(InstanceType::t1_micro); + request.SetStartTime(Aws::Utils::DateTime::Now() - std::chrono::milliseconds(1)); + request.SetMaxResults(10); + + size_t totalSpotPrices = 0; + auto outcome = ec2Client->DescribeSpotPriceHistory(request); + + while (outcome.IsSuccess()) { + const auto& result = outcome.GetResult(); + totalSpotPrices += result.GetSpotPriceHistory().size(); + + if (!Aws::EC2::Pagination::DescribeSpotPriceHistoryPaginationTraits::HasMoreResults(result)) { + break; + } + + Aws::EC2::Pagination::DescribeSpotPriceHistoryPaginationTraits::SetNextRequest(result, request); + outcome = ec2Client->DescribeSpotPriceHistory(request); + } + + ASSERT_TRUE(outcome.IsSuccess()); + // Should have at least one spot price entry + EXPECT_GE(totalSpotPrices, 1u); +} + +TEST_F(EC2PaginationTest, TestSpotPriceHistoryMultipleIteration) { + DescribeSpotPriceHistoryRequest request; + request.SetAvailabilityZone("us-east-1a"); + request.AddProductDescriptions("Linux/UNIX (Amazon VPC)"); + request.AddInstanceTypes(InstanceType::t1_micro); + request.SetStartTime(Aws::Utils::DateTime::Now() - std::chrono::milliseconds(1)); + request.SetMaxResults(5); + + // First iteration + size_t firstCount = 0; + auto outcome = ec2Client->DescribeSpotPriceHistory(request); + + while (outcome.IsSuccess()) { + const auto& result = outcome.GetResult(); + firstCount += result.GetSpotPriceHistory().size(); + + if (!Aws::EC2::Pagination::DescribeSpotPriceHistoryPaginationTraits::HasMoreResults(result)) { + break; + } + + Aws::EC2::Pagination::DescribeSpotPriceHistoryPaginationTraits::SetNextRequest(result, request); + outcome = ec2Client->DescribeSpotPriceHistory(request); + } + + ASSERT_TRUE(outcome.IsSuccess()); + + // Reset for second iteration + request = DescribeSpotPriceHistoryRequest(); + request.SetAvailabilityZone("us-east-1a"); + request.AddProductDescriptions("Linux/UNIX (Amazon VPC)"); + request.AddInstanceTypes(InstanceType::t1_micro); + request.SetStartTime(Aws::Utils::DateTime::Now() - std::chrono::milliseconds(1)); + request.SetMaxResults(5); + + // Second iteration + size_t secondCount = 0; + outcome = ec2Client->DescribeSpotPriceHistory(request); + + while (outcome.IsSuccess()) { + const auto& result = outcome.GetResult(); + secondCount += result.GetSpotPriceHistory().size(); + + if (!Aws::EC2::Pagination::DescribeSpotPriceHistoryPaginationTraits::HasMoreResults(result)) { + break; + } + + Aws::EC2::Pagination::DescribeSpotPriceHistoryPaginationTraits::SetNextRequest(result, request); + outcome = ec2Client->DescribeSpotPriceHistory(request); + } + + ASSERT_TRUE(outcome.IsSuccess()); + EXPECT_EQ(firstCount, secondCount); // Should get same results +} + +TEST_F(EC2PaginationTest, TestManualPaginationWithNextToken) { + DescribeSpotPriceHistoryRequest request; + request.SetAvailabilityZone("us-east-1a"); + request.AddProductDescriptions("Linux/UNIX (Amazon VPC)"); + request.AddInstanceTypes(InstanceType::t1_micro); + request.SetStartTime(Aws::Utils::DateTime::Now() - std::chrono::hours(24)); // Last 24 hours for more data + request.SetMaxResults(3); + + Aws::Vector allSpotPrices; + + do { + auto outcome = ec2Client->DescribeSpotPriceHistory(request); + ASSERT_TRUE(outcome.IsSuccess()); + + const auto& result = outcome.GetResult(); + for (const auto& spotPrice : result.GetSpotPriceHistory()) { + allSpotPrices.push_back(spotPrice); + } + + if (!result.GetNextToken().empty()) { + request.SetNextToken(result.GetNextToken()); + } else { + break; + } + } while (true); + + // Should have at least some spot price data + EXPECT_GE(allSpotPrices.size(), 1u); +} \ No newline at end of file diff --git a/tests/aws-cpp-sdk-s3-integration-tests/ListObjectsV2PaginationIntegrationTest.cpp b/tests/aws-cpp-sdk-s3-integration-tests/ListObjectsV2PaginationIntegrationTest.cpp new file mode 100644 index 000000000000..1f345d53b2d5 --- /dev/null +++ b/tests/aws-cpp-sdk-s3-integration-tests/ListObjectsV2PaginationIntegrationTest.cpp @@ -0,0 +1,175 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace Aws; +using namespace Aws::S3; +using namespace Aws::S3::Model; + +namespace { + static const char* ALLOCATION_TAG = "ListObjectsV2PaginationTest"; + const size_t OBJECT_COUNT = 15; + const size_t MAX_KEYS = 3; +} + +class ListObjectsV2PaginationTest : public Aws::Testing::AwsCppSdkGTestSuite { +protected: + std::shared_ptr s3Client; + Aws::String bucketName; + Aws::String emptyBucketName; + + void SetUp() override { + Aws::SDKOptions options; + Aws::InitAPI(options); + + s3Client = Aws::MakeShared(ALLOCATION_TAG); + bucketName = CalculateBucketName("listobjectsv2paginationtest"); + emptyBucketName = CalculateBucketName("listobjectsv2emptytest"); + + CreateBucketRequest createRequest; + createRequest.SetBucket(bucketName); + s3Client->CreateBucket(createRequest); + + createRequest.SetBucket(emptyBucketName); + s3Client->CreateBucket(createRequest); + + // Create test objects + for (size_t i = 1; i <= OBJECT_COUNT; ++i) { + Aws::StringStream ss; + ss << "key-" << std::setfill('0') << std::setw(2) << i; + CreateTestObject(ss.str()); + } + } + + void TearDown() override { + // Delete all objects + ListObjectsV2Request listRequest; + listRequest.SetBucket(bucketName); + auto listOutcome = s3Client->ListObjectsV2(listRequest); + if (listOutcome.IsSuccess()) { + for (const auto& object : listOutcome.GetResult().GetContents()) { + DeleteObjectRequest deleteRequest; + deleteRequest.SetBucket(bucketName); + deleteRequest.SetKey(object.GetKey()); + s3Client->DeleteObject(deleteRequest); + } + } + + DeleteBucketRequest deleteRequest; + deleteRequest.SetBucket(bucketName); + s3Client->DeleteBucket(deleteRequest); + + deleteRequest.SetBucket(emptyBucketName); + s3Client->DeleteBucket(deleteRequest); + + Aws::SDKOptions options; + Aws::ShutdownAPI(options); + } + + Aws::String CalculateBucketName(const Aws::String& bucketPrefix) { + return Aws::Testing::GetAwsResourcePrefix() + bucketPrefix; + } + + void CreateTestObject(const Aws::String& key) { + PutObjectRequest putRequest; + putRequest.SetBucket(bucketName); + putRequest.SetKey(key); + + auto data = Aws::MakeShared(ALLOCATION_TAG); + *data << "Test data for " << key; + putRequest.SetBody(data); + + s3Client->PutObject(putRequest); + } +}; + +TEST_F(ListObjectsV2PaginationTest, TestPaginationOnEmptyBucket) { + ListObjectsV2Request request; + request.SetBucket(emptyBucketName); + request.SetMaxKeys(MAX_KEYS); + + size_t objectCount = 0; + auto outcome = s3Client->ListObjectsV2(request); + + while (outcome.IsSuccess()) { + const auto& result = outcome.GetResult(); + objectCount += result.GetContents().size(); + + if (!Aws::S3::Pagination::ListObjectsV2PaginationTraits::HasMoreResults(result)) { + break; + } + + Aws::S3::Pagination::ListObjectsV2PaginationTraits::SetNextRequest(result, request); + outcome = s3Client->ListObjectsV2(request); + } + + ASSERT_TRUE(outcome.IsSuccess()); + EXPECT_EQ(0u, objectCount); +} + +TEST_F(ListObjectsV2PaginationTest, TestPaginationOnNonEmptyBucket) { + ListObjectsV2Request request; + request.SetBucket(bucketName); + request.SetMaxKeys(MAX_KEYS); + + size_t objectCount = 0; + size_t pageCount = 0; + auto outcome = s3Client->ListObjectsV2(request); + + while (outcome.IsSuccess()) { + const auto& result = outcome.GetResult(); + objectCount += result.GetContents().size(); + pageCount++; + + if (!Aws::S3::Pagination::ListObjectsV2PaginationTraits::HasMoreResults(result)) { + break; + } + + Aws::S3::Pagination::ListObjectsV2PaginationTraits::SetNextRequest(result, request); + outcome = s3Client->ListObjectsV2(request); + } + + ASSERT_TRUE(outcome.IsSuccess()); + EXPECT_EQ(OBJECT_COUNT, objectCount); + EXPECT_GT(pageCount, 1u); // Should have multiple pages with MaxKeys=3 +} + +TEST_F(ListObjectsV2PaginationTest, TestManualPaginationLoop) { + ListObjectsV2Request request; + request.SetBucket(bucketName); + request.SetMaxKeys(MAX_KEYS); + + Aws::Vector allKeys; + + do { + auto outcome = s3Client->ListObjectsV2(request); + ASSERT_TRUE(outcome.IsSuccess()); + + const auto& result = outcome.GetResult(); + for (const auto& object : result.GetContents()) { + allKeys.push_back(object.GetKey()); + } + + if (!result.GetIsTruncated()) { + break; + } + + request.SetContinuationToken(result.GetNextContinuationToken()); + } while (true); + + EXPECT_EQ(OBJECT_COUNT, allKeys.size()); +} From 2062a65ad45c6c90a9ce4c973650cc943a15c91d Mon Sep 17 00:00:00 2001 From: kai lin Date: Thu, 22 Jan 2026 15:52:06 -0500 Subject: [PATCH 33/46] added a patch to fix std string usage --- .../ScanPaginationIntegrationTest.cpp | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/tests/aws-cpp-sdk-dynamodb-integration-tests/ScanPaginationIntegrationTest.cpp b/tests/aws-cpp-sdk-dynamodb-integration-tests/ScanPaginationIntegrationTest.cpp index d43c8f8a8aa6..ba8d0ca8c2d8 100644 --- a/tests/aws-cpp-sdk-dynamodb-integration-tests/ScanPaginationIntegrationTest.cpp +++ b/tests/aws-cpp-sdk-dynamodb-integration-tests/ScanPaginationIntegrationTest.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -17,7 +18,6 @@ #include #include #include -#include using namespace Aws; using namespace Aws::DynamoDB; @@ -36,9 +36,6 @@ class ScanPaginationTest : public Aws::Testing::AwsCppSdkGTestSuite { Aws::String tableName; void SetUp() override { - Aws::SDKOptions options; - Aws::InitAPI(options); - dynamoClient = Aws::MakeShared(ALLOCATION_TAG); tableName = CalculateTableName("scan-paginator-test"); @@ -50,9 +47,6 @@ class ScanPaginationTest : public Aws::Testing::AwsCppSdkGTestSuite { DeleteTableRequest deleteRequest; deleteRequest.SetTableName(tableName); dynamoClient->DeleteTable(deleteRequest); - - Aws::SDKOptions options; - Aws::ShutdownAPI(options); } Aws::String CalculateTableName(const Aws::String& tablePrefix) { @@ -79,24 +73,32 @@ class ScanPaginationTest : public Aws::Testing::AwsCppSdkGTestSuite { createRequest.SetProvisionedThroughput(throughput); auto outcome = dynamoClient->CreateTable(createRequest); - ASSERT_TRUE(outcome.IsSuccess()); + AWS_ASSERT_SUCCESS(outcome); + + WaitUntilActive(tableName); + } + + DescribeTableResult WaitUntilActive(const Aws::String& tableName) { + DescribeTableRequest describeTableRequest; + describeTableRequest.SetTableName(tableName); + + DescribeTableOutcome outcome = dynamoClient->DescribeTable(describeTableRequest); + while (outcome.IsSuccess() && outcome.GetResult().GetTable().GetTableStatus() != TableStatus::ACTIVE) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + outcome = dynamoClient->DescribeTable(describeTableRequest); + } - // Wait for table to be active (simplified) - std::this_thread::sleep_for(std::chrono::seconds(10)); + return outcome.GetResult(); } void PutTestData() { - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution<> dis(0, ITEM_COUNT - 1); - for (size_t i = 0; i < ITEM_COUNT; ++i) { PutItemRequest putRequest; putRequest.SetTableName(tableName); Aws::Map item; - item[HASH_KEY_NAME] = AttributeValue().SetN(std::to_string(i)); - item[ATTRIBUTE_FOO] = AttributeValue().SetN(std::to_string(dis(gen))); + item[HASH_KEY_NAME] = AttributeValue().SetN(Aws::Utils::StringUtils::to_string(i)); + item[ATTRIBUTE_FOO] = AttributeValue().SetN(Aws::Utils::StringUtils::to_string(i * 2)); putRequest.SetItem(item); auto outcome = dynamoClient->PutItem(putRequest); From e70aa806197e24de91ef6690b1b7a35e10a31e8d Mon Sep 17 00:00:00 2001 From: kai lin Date: Thu, 22 Jan 2026 15:53:41 -0500 Subject: [PATCH 34/46] changed variable naming from c2j to smithy and moved paginationCodegenPlugin to templates --- .../generators/CompilationTestParser.java | 8 ++-- .../generators/FeatureParser.java | 16 +++---- .../generators/ServiceNameUtil.java | 30 +------------ .../generators/ShapeUtil.java | 44 ++++++++++++++++--- .../PaginationClientHeaderGenerator.java | 24 +++++----- .../PaginationCodegenPlugin.java | 6 +-- .../PaginationCompilationTestGenerator.java | 14 +++--- .../templates/PaginationTraitsGenerator.java | 26 +++++------ 8 files changed, 87 insertions(+), 81 deletions(-) rename tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/{ => templates}/PaginationCodegenPlugin.java (95%) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CompilationTestParser.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CompilationTestParser.java index afcaac07d93b..7c8d4ed41312 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CompilationTestParser.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/CompilationTestParser.java @@ -17,15 +17,15 @@ public class CompilationTestParser { private final CppWriterDelegator writerDelegator; private final String testType; private final Consumer renderFunction; - private final Map c2jMap; + private final Map serviceMap; public CompilationTestParser(PluginContext context, ServiceShape service, List operations, - String testType, Consumer renderFunction, Map c2jMap) { + String testType, Consumer renderFunction, Map serviceMap) { this.service = service; this.writerDelegator = new CppWriterDelegator(context.getFileManifest()); this.testType = testType; this.renderFunction = renderFunction; - this.c2jMap = c2jMap; + this.serviceMap = serviceMap; } public void run() { @@ -35,7 +35,7 @@ public void run() { private void generateCompilationTest() { String serviceName = ServiceNameUtil.getServiceName(service); - String c2jServiceName = ServiceNameUtil.getC2jServiceName(service, c2jMap); + String c2jServiceName = ServiceNameUtil.getSmithyServiceName(service, serviceMap); writerDelegator.useFileWriter( "generated/tests/" + c2jServiceName + "-gen-tests/" + serviceName + testType + "CompilationTests.cpp", diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/FeatureParser.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/FeatureParser.java index 4d70ac642efe..6d76901b0242 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/FeatureParser.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/FeatureParser.java @@ -17,7 +17,7 @@ public class FeatureParser { private final ServiceShape service; private final List operations; private final CppWriterDelegator writerDelegator; - private final Map c2jMap; + private final Map serviceMap; private final String featureName; public FeatureParser(PluginContext context, ServiceShape service, List operations, String featureName) { @@ -27,8 +27,8 @@ public FeatureParser(PluginContext context, ServiceShape service, List operat this.featureName = featureName; this.writerDelegator = new CppWriterDelegator(context.getFileManifest()); - // Initialize c2j map - this.c2jMap = new HashMap<>(); + // Initialize service map + this.serviceMap = new HashMap<>(); ObjectNode settings = context.getSettings(); if (settings.containsMember("c2jMap")) { Node c2jMapNode = settings.expectMember("c2jMap"); @@ -36,7 +36,7 @@ public FeatureParser(PluginContext context, ServiceShape service, List operat String jsonStr = c2jMapNode.expectStringNode().getValue(); ObjectNode mapNode = Node.parseJsonWithComments(jsonStr).expectObjectNode(); mapNode.getMembers().forEach((key, value) -> { - this.c2jMap.put(key.getValue(), value.expectStringNode().getValue()); + this.serviceMap.put(key.getValue(), value.expectStringNode().getValue()); }); } } @@ -49,10 +49,10 @@ public void run(Consumer> generationLogic) { public void generateClientHeader(String fileName, Consumer generator) { String serviceName = ServiceNameUtil.getServiceName(service); - String c2jServiceName = ServiceNameUtil.getC2jServiceName(service, c2jMap); + String smithyServiceName = ServiceNameUtil.getSmithyServiceName(service, serviceMap); writerDelegator.useFileWriter( - "include/aws/" + c2jServiceName + "/" + fileName, + "include/aws/" + smithyServiceName + "/" + fileName, generator ); } @@ -61,7 +61,7 @@ public void generateClientHeader(String fileName, Consumer generator) public ServiceShape getService() { return service; } public List getOperations() { return operations; } public String getFeatureName() { return featureName; } - public Map getC2jMap() { return c2jMap; } + public Map getServiceMap() { return serviceMap; } public String getServiceName() { return ServiceNameUtil.getServiceName(service); } - public String getC2jServiceName() { return ServiceNameUtil.getC2jServiceName(service, c2jMap); } + public String getSmithyServiceName() { return ServiceNameUtil.getSmithyServiceName(service, serviceMap); } } \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java index eabe01e6763e..60be3b84ab1d 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java @@ -115,14 +115,6 @@ public static String getServiceName(ServiceShape service) { return sanitized; } - // TODO: Investigate if getServiceNameLowercase and getServiceNameUpperCamel can be refactored - // to replace getServiceName entirely, ensuring all existing functionality is preserved - public static String getServiceNameLowercase(ServiceShape service) { - return getServiceName(service).toLowerCase(); - } - - // TODO: Investigate if getServiceNameLowercase and getServiceNameUpperCamel can be refactored - // to replace getServiceName entirely, ensuring all existing functionality is preserved public static String getServiceNameUpperCamel(ServiceShape service) { String serviceName = getServiceName(service); return serviceName.substring(0, 1).toUpperCase() + serviceName.substring(1); @@ -133,7 +125,7 @@ private static String sanitizeServiceAbbreviation(String serviceAbbreviation) { return serviceAbbreviation.replace(" ", "").replace("-", "").replace("_", "").replace("Amazon", "").replace("AWS", "").replace("/", ""); } - public static String getC2jServiceName(ServiceShape service, Map c2jMap) { + public static String getSmithyServiceName(ServiceShape service, Map serviceMap) { String sdkId = service.getTrait(ServiceTrait.class) .map(ServiceTrait::getSdkId) .orElse(service.getId().getName()) @@ -141,24 +133,6 @@ public static String getC2jServiceName(ServiceShape service, Map .toLowerCase() .replace(" ", "-"); - return c2jMap != null ? c2jMap.getOrDefault(sdkId, sdkId) : sdkId; - } - - /** - * Gets the client method name for an operation. - * CloudFront requires a version suffix for backwards compatibility with legacy C2J code generation. - * The legacy C2J generator appended version suffixes to CloudFront operation names in the generated code. - * - * TODO: Consider moving to a map if more services require version suffixes in the future - * - * @param opName The base operation name from the Smithy model - * @param c2jServiceName The C2J service name (e.g., "cloudfront") - * @return The operation name with version suffix if needed (e.g., "ListDistributions2020_05_31") - */ - public static String getClientMethodName(String opName, String c2jServiceName) { - if ("cloudfront".equals(c2jServiceName)) { - return opName + "2020_05_31"; - } - return opName; + return serviceMap != null ? serviceMap.getOrDefault(sdkId, sdkId) : sdkId; } } \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java index 404a542b304b..48822f6956e6 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java @@ -44,6 +44,20 @@ public class ShapeUtil { "medialive", Set.of("ListChannelPlacementGroups", "ListClusters", "ListNetworks", "ListNodes") ); + /** + * Legacy operation name version suffixes required for backwards compatibility. + * The legacy C2J code generator appended API version suffixes to operation names for certain services. + * This maintains compatibility with existing generated code that depends on these versioned method names. + * + * CloudFront: Uses "2020_05_31" suffix (the API version when C++ SDK generation was standardized) + * - Example: "ListDistributions" becomes "ListDistributions2020_05_31" + * - Required because existing C++ code expects these versioned method names + * - CloudFront has had multiple API versions, and the C2J generator historically used version suffixes + */ + private static final Map OPERATION_VERSION_SUFFIXES = Map.of( + "cloudfront", "2020_05_31" + ); + /** * C2J/Smithy model mismatches: pagination tokens that are integers in C2J but strings in Smithy. * @@ -74,16 +88,32 @@ public static Set getReferences(Model model, Shape root) { return refs; } + /** + * Gets the operation method name with legacy version suffix if required. + * + * Some services require version suffixes appended to operation names for backwards compatibility + * with the legacy C2J code generator. This ensures existing C++ code continues to work with + * the expected method names. + * + * @param opName The base operation name from the Smithy model + * @param smithyServiceName The Smithy service name (e.g., "cloudfront") + * @return The operation name with version suffix if needed (e.g., "ListDistributions2020_05_31") + */ + public static String getOperationMethodName(String opName, String smithyServiceName) { + String versionSuffix = OPERATION_VERSION_SUFFIXES.get(smithyServiceName); + return versionSuffix != null ? opName + versionSuffix : opName; + } + /** * Checks if a pagination token should be treated as numeric due to C2J/Smithy model mismatch. * - * @param c2jServiceName The C2J service name + * @param smithyServiceName The Smithy service name * @param operationName The operation name * @param tokenName The pagination token name * @return true if token is numeric in C2J but string in Smithy */ - public static boolean isNumericTokenOverride(String c2jServiceName, String operationName, String tokenName) { - Map> serviceOverrides = NUMERIC_TOKEN_OVERRIDES.get(c2jServiceName); + public static boolean isNumericTokenOverride(String smithyServiceName, String operationName, String tokenName) { + Map> serviceOverrides = NUMERIC_TOKEN_OVERRIDES.get(smithyServiceName); if (serviceOverrides == null) { return false; } @@ -102,17 +132,17 @@ public static boolean isNumericTokenOverride(String c2jServiceName, String opera * * @param model The Smithy model * @param operation The operation shape - * @param c2jServiceName The C2J service name + * @param smithyServiceName The Smithy service name * @return "Response" for EC2 protocol, "SdkResult" if naming conflict exists, otherwise "Result" */ - public static String getResultSuffix(Model model, OperationShape operation, String c2jServiceName) { + public static String getResultSuffix(Model model, OperationShape operation, String smithyServiceName) { // EC2 protocol services rename all Result shapes to Response - if ("ec2".equals(c2jServiceName)) { + if ("ec2".equals(smithyServiceName)) { return "Response"; } // C2J backward compatibility: preserve SdkResult for operations that had collisions in legacy models - Set legacyOps = LEGACY_SDK_RESULT_OPERATIONS.get(c2jServiceName); + Set legacyOps = LEGACY_SDK_RESULT_OPERATIONS.get(smithyServiceName); if (legacyOps != null && legacyOps.contains(operation.getId().getName())) { return "SdkResult"; } diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java index 7c9235fa5b61..15d66d2288dc 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java @@ -6,6 +6,8 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; import com.amazonaws.util.awsclientsmithygenerator.generators.OperationData; +import com.amazonaws.util.awsclientsmithygenerator.generators.ServiceNameUtil; +import com.amazonaws.util.awsclientsmithygenerator.generators.ShapeUtil; import software.amazon.smithy.model.shapes.ServiceShape; import software.amazon.smithy.aws.traits.ServiceTrait; import software.amazon.smithy.model.traits.PaginatedTrait; @@ -16,19 +18,19 @@ public class PaginationClientHeaderGenerator { private final ServiceShape service; private final List> paginatedOps; - private final Map c2jMap; - private final String c2jServiceName; + private final Map serviceMap; + private final String smithyServiceName; - public PaginationClientHeaderGenerator(ServiceShape service, List> paginatedOps, Map c2jMap) { + public PaginationClientHeaderGenerator(ServiceShape service, List> paginatedOps, Map serviceMap) { this.service = service; this.paginatedOps = paginatedOps; - this.c2jMap = c2jMap; - this.c2jServiceName = ServiceNameUtil.getC2jServiceName(service, c2jMap); + this.serviceMap = serviceMap; + this.smithyServiceName = ServiceNameUtil.getSmithyServiceName(service, serviceMap); } public void render(CppWriter writer) { String serviceName = ServiceNameUtil.getServiceName(service); - String c2jServiceName = ServiceNameUtil.getC2jServiceName(service, c2jMap); + String smithyServiceName = ServiceNameUtil.getSmithyServiceName(service, serviceMap); // Header and includes writer.write("/**"); @@ -38,18 +40,18 @@ public void render(CppWriter writer) { writer.write(""); writer.write("#pragma once"); - renderIncludes(writer, serviceName, c2jServiceName); + renderIncludes(writer, serviceName, smithyServiceName); renderNamespaces(writer, serviceName); } - private void renderIncludes(CppWriter writer, String serviceName, String c2jServiceName) { + private void renderIncludes(CppWriter writer, String serviceName, String smithyServiceName) { String classPrefix = ServiceNameUtil.getServiceNameUpperCamel(service); - writer.writeInclude("aws/" + c2jServiceName + "/" + classPrefix + "Client.h"); + writer.writeInclude("aws/" + smithyServiceName + "/" + classPrefix + "Client.h"); writer.writeInclude("aws/core/utils/pagination/Paginator.h"); for (OperationData data : paginatedOps) { String opName = data.getOperation().getId().getName(); - writer.writeInclude("aws/" + c2jServiceName + "/model/pagination/" + opName + "PaginationTraits.h"); + writer.writeInclude("aws/" + smithyServiceName + "/model/pagination/" + opName + "PaginationTraits.h"); } writer.write(""); } @@ -62,7 +64,7 @@ private void renderNamespaces(CppWriter writer, String serviceName) { for (OperationData data : paginatedOps) { String opName = data.getOperation().getId().getName(); - String methodName = ServiceNameUtil.getClientMethodName(opName, c2jServiceName); + String methodName = ShapeUtil.getOperationMethodName(opName, smithyServiceName); writer.write("using $LPaginator = Aws::Utils::Pagination::PagePaginator<$LClient, Model::$LRequest, Pagination::$LPaginationTraits>;", opName, classPrefix, methodName, opName); } diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java similarity index 95% rename from tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java rename to tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java index 489392ea6849..24546026b545 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/PaginationCodegenPlugin.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java @@ -46,7 +46,7 @@ public void execute(PluginContext context) { // Generate client pagination header featureParser.generateClientHeader( serviceName + "ClientPagination.h", - writer -> new PaginationClientHeaderGenerator(featureParser.getService(), featureParser.getOperations(), featureParser.getC2jMap()).render(writer) + writer -> new PaginationClientHeaderGenerator(featureParser.getService(), featureParser.getOperations(), featureParser.getServiceMap()).render(writer) ); // Generate pagination traits headers @@ -54,13 +54,13 @@ public void execute(PluginContext context) { featureParser.getContext(), featureParser.getService(), featureParser.getOperations(), - featureParser.getC2jServiceName() + featureParser.getSmithyServiceName() ); traitsGenerator.write(); }); // Generate compilation test - PaginationCompilationTestGenerator testGenerator = new PaginationCompilationTestGenerator(context, service, paginatedOps, parser.getC2jMap()); + PaginationCompilationTestGenerator testGenerator = new PaginationCompilationTestGenerator(context, service, paginatedOps, parser.getServiceMap()); testGenerator.run(); } } diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java index 0bcf0ab3f4b2..faafa09db679 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java @@ -16,18 +16,18 @@ public class PaginationCompilationTestGenerator { private final CompilationTestParser> parser; private final List> allPaginatedOps; - private final Map c2jMap; + private final Map serviceMap; - public PaginationCompilationTestGenerator(PluginContext context, ServiceShape service, List> allPaginatedOps, Map c2jMap) { + public PaginationCompilationTestGenerator(PluginContext context, ServiceShape service, List> allPaginatedOps, Map serviceMap) { this.allPaginatedOps = allPaginatedOps; - this.c2jMap = c2jMap; + this.serviceMap = serviceMap; this.parser = new CompilationTestParser<>( context, service, allPaginatedOps, "Pagination", this::render, - c2jMap + serviceMap ); } @@ -75,14 +75,14 @@ private void writeIncludes(CppWriter writer) { for (OperationData paginationData : allPaginatedOps) { ServiceShape service = paginationData.getService(); String serviceName = ServiceNameUtil.getServiceNameUpperCamel(service); - String c2jServiceName = ServiceNameUtil.getC2jServiceName(service, c2jMap); + String smithyServiceName = ServiceNameUtil.getSmithyServiceName(service, serviceMap); // Collect unique client headers - clientHeaders.add("aws/" + c2jServiceName + "/" + serviceName + "ClientPagination.h"); + clientHeaders.add("aws/" + smithyServiceName + "/" + serviceName + "ClientPagination.h"); // Collect unique trait headers String operationName = paginationData.getOperation().getId().getName(); - traitHeaders.add("aws/" + c2jServiceName + "/model/pagination/" + operationName + "PaginationTraits.h"); + traitHeaders.add("aws/" + smithyServiceName + "/model/pagination/" + operationName + "PaginationTraits.h"); } // Write unique client headers diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java index f91c2d3abf8f..b12cd1d6c6c5 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java @@ -20,15 +20,15 @@ public class PaginationTraitsGenerator { private final PluginContext context; private final ServiceShape service; private final List> paginatedOps; - private final String c2jServiceName; + private final String smithyServiceName; private final CppWriterDelegator writerDelegator; - public PaginationTraitsGenerator(PluginContext context, ServiceShape service, List> paginatedOps, String c2jServiceName) { + public PaginationTraitsGenerator(PluginContext context, ServiceShape service, List> paginatedOps, String smithyServiceName) { this.context = context; this.service = service; this.paginatedOps = paginatedOps; - this.c2jServiceName = c2jServiceName; + this.smithyServiceName = smithyServiceName; this.writerDelegator = new CppWriterDelegator(context.getFileManifest()); } @@ -36,7 +36,7 @@ public void write() { String serviceName = ServiceNameUtil.getServiceName(service); for (OperationData data : paginatedOps) { - String fileName = "include/aws/" + c2jServiceName + "/model/pagination/" + data.getOperation().getId().getName() + "PaginationTraits.h"; + String fileName = "include/aws/" + smithyServiceName + "/model/pagination/" + data.getOperation().getId().getName() + "PaginationTraits.h"; writerDelegator.useFileWriter(fileName, writer -> { generateTraitsHeader(writer, data, serviceName); @@ -62,12 +62,12 @@ private void generateTraitsHeader(CppWriter writer, OperationData { // Use detected suffix to match C2J renameShape logic - String methodName = ServiceNameUtil.getClientMethodName(opName, c2jServiceName); + String methodName = ShapeUtil.getOperationMethodName(opName, smithyServiceName); writer.write(" using RequestType = Model::$LRequest;", methodName) .write(" using ResultType = Model::$L$L;", methodName, resultSuffix) .write(" using OutcomeType = Model::$LOutcome;", methodName) @@ -216,7 +216,7 @@ else if (hasTopLevelMember(op, outToken)) { // TODO: Consider inlining this method since it's only called once and just delegates to ShapeUtil. // Verify no other generators use this pattern before removing. private String getResultSuffix(OperationShape op) { - return ShapeUtil.getResultSuffix(context.getModel(), op, c2jServiceName); + return ShapeUtil.getResultSuffix(context.getModel(), op, smithyServiceName); } @@ -276,7 +276,7 @@ private boolean hasTopLevelMember(OperationShape op, String memberName) { private boolean isNumericToken(OperationShape op, String wrapperMember, String tokenName) { // Check for C2J/Smithy model mismatch overrides first - if (ShapeUtil.isNumericTokenOverride(c2jServiceName, op.getId().getName(), tokenName)) { + if (ShapeUtil.isNumericTokenOverride(smithyServiceName, op.getId().getName(), tokenName)) { return true; } From 0da35f4b7f436a4cee00dd92d5980490d1a5bb63 Mon Sep 17 00:00:00 2001 From: kai lin Date: Thu, 22 Jan 2026 16:58:13 -0500 Subject: [PATCH 35/46] refactor code to shapeutil --- .../generators/ServiceNameUtil.java | 7 +- .../generators/ShapeUtil.java | 152 +++++++++++------ .../templates/PaginationTraitsGenerator.java | 154 ++++------------- .../codegen/cpp-pagination/smithy-build.json | 160 ++++++++++++++++++ 4 files changed, 297 insertions(+), 176 deletions(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java index 60be3b84ab1d..d97626c7cfca 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ServiceNameUtil.java @@ -116,8 +116,11 @@ public static String getServiceName(ServiceShape service) { } public static String getServiceNameUpperCamel(ServiceShape service) { - String serviceName = getServiceName(service); - return serviceName.substring(0, 1).toUpperCase() + serviceName.substring(1); + return capitalize(getServiceName(service)); + } + + public static String capitalize(String str) { + return str.substring(0, 1).toUpperCase() + str.substring(1); } // Match C2jModelToGeneratorModelTransformer.sanitizeServiceAbbreviation() exactly diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java index 48822f6956e6..cc9ea2b0ecff 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/ShapeUtil.java @@ -6,6 +6,7 @@ import software.amazon.smithy.model.Model; import software.amazon.smithy.model.shapes.*; +import software.amazon.smithy.model.traits.Trait; import java.util.*; public class ShapeUtil { @@ -59,11 +60,11 @@ public class ShapeUtil { ); /** - * C2J/Smithy model mismatches: pagination tokens that are integers in C2J but strings in Smithy. + * C2J/Smithy model mismatches: tokens that are integers in C2J but strings in Smithy. * * Background: - * Some services have pagination tokens that were modeled as integers in C2J but changed to - * strings in Smithy models. The C2J-generated code uses int types, so pagination traits must + * Some services have tokens that were modeled as integers in C2J but changed to + * strings in Smithy models. The C2J-generated code uses int types, so traits must * use `!= 0` checks instead of `.empty()` checks. * * Map format: service-name -> Map of operation-name -> token-name @@ -105,20 +106,39 @@ public static String getOperationMethodName(String opName, String smithyServiceN } /** - * Checks if a pagination token should be treated as numeric due to C2J/Smithy model mismatch. + * Checks if a token is numeric (integer or long type). + * First checks for C2J/Smithy model mismatch overrides, then inspects the actual shape type. * + * @param model The Smithy model + * @param op The operation shape * @param smithyServiceName The Smithy service name - * @param operationName The operation name - * @param tokenName The pagination token name - * @return true if token is numeric in C2J but string in Smithy + * @param wrapperMember The wrapper member name (null if token is at top level) + * @param tokenName The token name + * @return true if the token is numeric */ - public static boolean isNumericTokenOverride(String smithyServiceName, String operationName, String tokenName) { + public static boolean isNumericToken(Model model, OperationShape op, String smithyServiceName, String wrapperMember, String tokenName) { + // Check for C2J/Smithy model mismatch overrides first Map> serviceOverrides = NUMERIC_TOKEN_OVERRIDES.get(smithyServiceName); - if (serviceOverrides == null) { - return false; + if (serviceOverrides != null) { + Set tokens = serviceOverrides.get(op.getId().getName()); + if (tokens != null && tokens.contains(tokenName)) { + return true; + } } - Set tokens = serviceOverrides.get(operationName); - return tokens != null && tokens.contains(tokenName); + + Optional tokenShape = getOutputStructure(model, op) + .flatMap(out -> { + if (wrapperMember == null) { + return out.getMember(tokenName); + } + return out.getMember(wrapperMember) + .flatMap(m -> model.getShape(m.getTarget())) + .flatMap(t -> t.asStructureShape()) + .flatMap(w -> w.getMember(tokenName)); + }) + .flatMap(member -> model.getShape(member.getTarget())); + + return tokenShape.map(ts -> ts instanceof IntegerShape || ts instanceof LongShape).orElse(false); } /** @@ -148,7 +168,8 @@ public static String getResultSuffix(Model model, OperationShape operation, Stri } String baseName = operation.getId().getName(); - Set allShapeNames = getAllShapeNames(model); + Set allShapeNames = new HashSet<>(); + model.shapes().forEach(s -> allShapeNames.add(s.getId().getName())); // Output shape name (used for legacy early-accept behavior) String outputShapeName = operation.getOutput().isPresent() @@ -156,7 +177,9 @@ public static String getResultSuffix(Model model, OperationShape operation, Stri : null; // For closer parity with the legacy Get/Set collision rule - Set outputMemberNames = getOutputMemberNames(model, operation); + Set outputMemberNames = getOutputStructure(model, operation) + .map(struct -> new HashSet<>(struct.getAllMembers().keySet())) + .orElse(new HashSet<>()); for (String suffix : RESULT_SUFFIXES) { String candidate = baseName + suffix; @@ -173,8 +196,18 @@ public static String getResultSuffix(Model model, OperationShape operation, Stri } // Closer parity with legacy intent (member-gated Get/Set collisions) - if (hasGetSetCollision(candidate, allShapeNames, outputMemberNames)) { - continue; + if (!outputMemberNames.isEmpty()) { + boolean hasCollision = false; + for (String shapeName : allShapeNames) { + if (outputMemberNames.contains(shapeName) && + (candidate.equals("Get" + shapeName) || candidate.equals("Set" + shapeName))) { + hasCollision = true; + break; + } + } + if (hasCollision) { + continue; + } } return suffix; @@ -184,42 +217,63 @@ public static String getResultSuffix(Model model, OperationShape operation, Stri throw new IllegalStateException("Unhandled result shape name conflict for operation: " + baseName); } - private static Set getAllShapeNames(Model model) { - Set names = new HashSet<>(); - model.shapes().forEach(s -> names.add(s.getId().getName())); - return names; + /** + * Gets the output structure shape for an operation, or null if not present or not a structure. + */ + private static Optional getOutputStructure(Model model, OperationShape op) { + return op.getOutput() + .flatMap(outputId -> model.getShape(outputId)) + .flatMap(shape -> shape.asStructureShape()); } - private static Set getOutputMemberNames(Model model, OperationShape op) { - // If no output or not a structure, return empty - if (!op.getOutput().isPresent()) { - return Collections.emptySet(); - } - ShapeId outputId = op.getOutputShape(); - Shape output = model.expectShape(outputId); - if (!output.isStructureShape()) { - return Collections.emptySet(); - } - StructureShape struct = output.asStructureShape().get(); - return new HashSet<>(struct.getAllMembers().keySet()); + /** + * Finds the wrapper member in an operation's output that contains the specified token. + * Used for token resolution when tokens are nested in wrapper structures. + * + * @param model The Smithy model + * @param op The operation shape + * @param tokenName The token name to find + * @return The wrapper member name, or null if not found + */ + public static String findWrapperMemberContainingToken(Model model, OperationShape op, String tokenName) { + return getOutputStructure(model, op) + .flatMap(outputShape -> + outputShape.getAllMembers().entrySet().stream() + .filter(entry -> model.getShape(entry.getValue().getTarget()) + .flatMap(t -> t.asStructureShape()) + .map(s -> s.getAllMembers().containsKey(tokenName)) + .orElse(false)) + .map(Map.Entry::getKey) + .findFirst() + ) + .orElse(null); } - private static boolean hasGetSetCollision(String candidate, - Set allShapeNames, - Set outputMemberNames) { - if (outputMemberNames.isEmpty()) { - return false; - } - - // Legacy logic: only treat GetX/SetX as conflict if X is both a known shape name and a member name - for (String shapeName : allShapeNames) { - if (!outputMemberNames.contains(shapeName)) { - continue; - } - if (candidate.equals("Get" + shapeName) || candidate.equals("Set" + shapeName)) { - return true; - } - } - return false; + /** + * Checks if an operation's output has a top-level member with the specified name. + * + * @param model The Smithy model + * @param op The operation shape + * @param memberName The member name to check + * @return true if the member exists at the top level + */ + public static boolean hasTopLevelMember(Model model, OperationShape op, String memberName) { + return getOutputStructure(model, op) + .map(outputShape -> outputShape.getAllMembers().containsKey(memberName)) + .orElse(false); + } + + /** + * Gets service-level token when operation-level traits are missing. + * + * @param service The service shape + * @param traitClass The trait class to look for + * @param tokenExtractor Function to extract the token from the trait + * @return The service-level token, or null if not defined + */ + public static String getServiceLevelToken(ServiceShape service, Class traitClass, java.util.function.Function> tokenExtractor) { + return service.getTrait(traitClass) + .map(trait -> tokenExtractor.apply(trait).orElse(null)) + .orElse(null); } } \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java index b12cd1d6c6c5..915488e20110 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java @@ -60,7 +60,7 @@ private void generateTraitsHeader(CppWriter writer, OperationData t.getOutputToken()); if (serviceLevelOutputToken != null) { - if (isNumericToken(op, null, serviceLevelOutputToken)) { - writer.write(" return result.Get$L() != 0;", capitalize(serviceLevelOutputToken)); + if (ShapeUtil.isNumericToken(context.getModel(), op, smithyServiceName, null, serviceLevelOutputToken)) { + writer.write(" return result.Get$L() != 0;", ServiceNameUtil.capitalize(serviceLevelOutputToken)); } else { - writer.write(" return !result.Get$L().empty();", capitalize(serviceLevelOutputToken)); + writer.write(" return !result.Get$L().empty();", ServiceNameUtil.capitalize(serviceLevelOutputToken)); } } else { writer.write(" return result.GetIsTruncated();"); @@ -164,13 +159,10 @@ else if (hasTopLevelMember(op, outToken)) { inToken = trait.getInputToken().get(); outToken = trait.getOutputToken().get(); } else { - // TODO: Check how legacy C2J code generation handles service-level pagination - // This is a temporary fix for AccessAnalyzer which uses service-level pagination config. - // We should investigate how the legacy generator in C2jModelToGeneratorModelTransformer - // or other legacy components handle service-level vs operation-level pagination traits - // and implement a more comprehensive solution that matches that behavior. - String serviceLevelInputToken = getServiceLevelInputToken(); - String serviceLevelOutputToken = getServiceLevelOutputToken(); + // Fallback to service-level pagination configuration when operation-level traits are missing. + // Some services like AccessAnalyzer define pagination tokens at the service level rather than per-operation. + String serviceLevelInputToken = ShapeUtil.getServiceLevelToken(service, software.amazon.smithy.model.traits.PaginatedTrait.class, t -> t.getInputToken()); + String serviceLevelOutputToken = ShapeUtil.getServiceLevelToken(service, software.amazon.smithy.model.traits.PaginatedTrait.class, t -> t.getOutputToken()); if (serviceLevelInputToken != null && serviceLevelOutputToken != null) { inToken = serviceLevelInputToken; outToken = serviceLevelOutputToken; @@ -183,25 +175,22 @@ else if (hasTopLevelMember(op, outToken)) { String[] parts = outToken.split("\\.", 2); String memberName = parts[0]; String nestedTokenName = parts[1]; - writer.write(" request.Set$L(result.Get$L().Get$L());", capitalize(inToken), capitalize(memberName), capitalize(nestedTokenName)); + writer.write(" request.Set$L(result.Get$L().Get$L());", ServiceNameUtil.capitalize(inToken), ServiceNameUtil.capitalize(memberName), ServiceNameUtil.capitalize(nestedTokenName)); } // Pattern B: Check if token is on top-level output - else if (hasTopLevelMember(op, outToken)) { - writer.write(" request.Set$L(result.Get$L());", capitalize(inToken), capitalize(outToken)); + else if (ShapeUtil.hasTopLevelMember(context.getModel(), op, outToken)) { + writer.write(" request.Set$L(result.Get$L());", ServiceNameUtil.capitalize(inToken), ServiceNameUtil.capitalize(outToken)); } // Pattern C: Find wrapper member containing the token else { - String wrapperMember = findWrapperMemberContainingToken(op, outToken); + String wrapperMember = ShapeUtil.findWrapperMemberContainingToken(context.getModel(), op, outToken); if (wrapperMember != null) { - writer.write(" request.Set$L(result.Get$L().Get$L());", capitalize(inToken), capitalize(wrapperMember), capitalize(outToken)); + writer.write(" request.Set$L(result.Get$L().Get$L());", ServiceNameUtil.capitalize(inToken), ServiceNameUtil.capitalize(wrapperMember), ServiceNameUtil.capitalize(outToken)); } else { writer.write(" (void)result; (void)request; // Token not found"); } } } else { - // TODO: Check AWS SDK C++ standard for handling null pagination tokens - // Should we throw an exception, log a warning, or silently ignore? - // Verify behavior with other AWS SDK implementations. writer.write(" (void)result; (void)request; // Unused parameters"); } }); @@ -212,89 +201,4 @@ else if (hasTopLevelMember(op, outToken)) { .writeNamespaceClose(serviceName) .writeNamespaceClose("Aws"); } - - // TODO: Consider inlining this method since it's only called once and just delegates to ShapeUtil. - // Verify no other generators use this pattern before removing. - private String getResultSuffix(OperationShape op) { - return ShapeUtil.getResultSuffix(context.getModel(), op, smithyServiceName); - } - - - // TODO: These service-level pagination helper methods are a temporary solution. - // We should investigate how the legacy C2J code generation system handles the precedence - // between operation-level and service-level pagination traits, and implement a solution - // that matches that behavior. This may involve: - // 1. Checking how C2jModelToGeneratorModelTransformer processes pagination - // 2. Understanding the inheritance model for pagination traits - // 3. Implementing proper trait resolution that matches legacy behavior - private String getServiceLevelInputToken() { - // Check if service has service-level pagination configuration - return service.getTrait(software.amazon.smithy.model.traits.PaginatedTrait.class) - .map(trait -> trait.getInputToken().orElse(null)) - .orElse(null); - } - - private String getServiceLevelOutputToken() { - // Check if service has service-level pagination configuration - return service.getTrait(software.amazon.smithy.model.traits.PaginatedTrait.class) - .map(trait -> trait.getOutputToken().orElse(null)) - .orElse(null); - } - - private String capitalize(String str) { - return str.substring(0, 1).toUpperCase() + str.substring(1); - } - - private String extractTokenName(String outToken) { - // Pagination token may be in format "MemberName.TokenName", extract just the token name - return outToken.contains(".") ? outToken.substring(outToken.lastIndexOf(".") + 1) : outToken; - } - - private String findWrapperMemberContainingToken(OperationShape op, String tokenName) { - return op.getOutput() - .flatMap(outputId -> context.getModel().getShape(outputId)) - .flatMap(shape -> shape.asStructureShape()) - .flatMap(outputShape -> - outputShape.getAllMembers().entrySet().stream() - .filter(entry -> context.getModel().getShape(entry.getValue().getTarget()) - .flatMap(t -> t.asStructureShape()) - .map(s -> s.getAllMembers().containsKey(tokenName)) - .orElse(false)) - .map(Map.Entry::getKey) - .findFirst() - ) - .orElse(null); - } - - private boolean hasTopLevelMember(OperationShape op, String memberName) { - return op.getOutput() - .flatMap(outputId -> context.getModel().getShape(outputId)) - .flatMap(shape -> shape.asStructureShape()) - .map(outputShape -> outputShape.getAllMembers().containsKey(memberName)) - .orElse(false); - } - - private boolean isNumericToken(OperationShape op, String wrapperMember, String tokenName) { - // Check for C2J/Smithy model mismatch overrides first - if (ShapeUtil.isNumericTokenOverride(smithyServiceName, op.getId().getName(), tokenName)) { - return true; - } - - Optional tokenShape = - op.getOutput() - .flatMap(outputId -> context.getModel().getShape(outputId)) - .flatMap(s -> s.asStructureShape()) - .flatMap(out -> { - if (wrapperMember == null) { - return out.getMember(tokenName); - } - return out.getMember(wrapperMember) - .flatMap(m -> context.getModel().getShape(m.getTarget())) - .flatMap(t -> t.asStructureShape()) - .flatMap(w -> w.getMember(tokenName)); - }) - .flatMap(member -> context.getModel().getShape(member.getTarget())); - - return tokenShape.map(ts -> ts instanceof IntegerShape || ts instanceof LongShape).orElse(false); - } -} +} \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination/smithy-build.json b/tools/code-generation/smithy/codegen/cpp-pagination/smithy-build.json index 40328dc60a77..1008552afa3d 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination/smithy-build.json +++ b/tools/code-generation/smithy/codegen/cpp-pagination/smithy-build.json @@ -1,6 +1,116 @@ { "version": "1.0", "projections": { + "accessanalyzer.2019-11-01": { + "imports": [ + "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/accessanalyzer.json" + ], + "plugins": { + "cpp-codegen-pagination-plugin": { + "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" + } + } + }, + "elasticache.2015-02-02": { + "imports": [ + "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/elasticache.json" + ], + "plugins": { + "cpp-codegen-pagination-plugin": { + "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" + } + } + }, + "bedrock-agent-runtime.2023-07-26": { + "imports": [ + "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/bedrock-agent-runtime.json" + ], + "plugins": { + "cpp-codegen-pagination-plugin": { + "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" + } + } + }, + "amp.2020-08-01": { + "imports": [ + "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/amp.json" + ], + "plugins": { + "cpp-codegen-pagination-plugin": { + "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" + } + } + }, + "chatbot.2017-10-11": { + "imports": [ + "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/chatbot.json" + ], + "plugins": { + "cpp-codegen-pagination-plugin": { + "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" + } + } + }, + "lex-models-v2.2020-08-07": { + "imports": [ + "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/lex-models-v2.json" + ], + "plugins": { + "cpp-codegen-pagination-plugin": { + "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" + } + } + }, + "transfer.2018-11-05": { + "imports": [ + "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/transfer.json" + ], + "plugins": { + "cpp-codegen-pagination-plugin": { + "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" + } + } + }, + "ecr.2015-09-21": { + "imports": [ + "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/ecr.json" + ], + "plugins": { + "cpp-codegen-pagination-plugin": { + "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" + } + } + }, + "migration-hub.2017-05-31": { + "imports": [ + "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/migration-hub.json" + ], + "plugins": { + "cpp-codegen-pagination-plugin": { + "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" + } + } + }, + "ec2.2016-11-15": { + "imports": [ + "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/ec2.json" + ], + "plugins": { + "cpp-codegen-pagination-plugin": { + "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" + } + } + }, + "b2bi.2022-06-23": { + "imports": [ + "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/b2bi.json" + ], + "plugins": { + "cpp-codegen-pagination-plugin": { + "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" + } + } + }, "s3.2006-03-01": { "imports": [ "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/s3.json" @@ -11,6 +121,56 @@ } } }, + "appintegrations.2020-07-29": { + "imports": [ + "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/appintegrations.json" + ], + "plugins": { + "cpp-codegen-pagination-plugin": { + "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" + } + } + }, + "amplify.2017-07-25": { + "imports": [ + "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/amplify.json" + ], + "plugins": { + "cpp-codegen-pagination-plugin": { + "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" + } + } + }, + "codestar-notifications.2019-10-15": { + "imports": [ + "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/codestar-notifications.json" + ], + "plugins": { + "cpp-codegen-pagination-plugin": { + "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" + } + } + }, + "cloudfront.2020-05-31": { + "imports": [ + "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/cloudfront.json" + ], + "plugins": { + "cpp-codegen-pagination-plugin": { + "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" + } + } + }, + "medialive.2017-10-14": { + "imports": [ + "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/medialive.json" + ], + "plugins": { + "cpp-codegen-pagination-plugin": { + "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" + } + } + }, "dynamodb.2012-08-10": { "imports": [ "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/dynamodb.json" From 55fdc0c5dacae9b435f86d77873048f9e0df7823 Mon Sep 17 00:00:00 2001 From: kai lin Date: Thu, 22 Jan 2026 17:04:10 -0500 Subject: [PATCH 36/46] WaitUntilActive method parameter tableName was shadowing the class member variable tableName --- .../ScanPaginationIntegrationTest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/aws-cpp-sdk-dynamodb-integration-tests/ScanPaginationIntegrationTest.cpp b/tests/aws-cpp-sdk-dynamodb-integration-tests/ScanPaginationIntegrationTest.cpp index ba8d0ca8c2d8..a7dc27adcf87 100644 --- a/tests/aws-cpp-sdk-dynamodb-integration-tests/ScanPaginationIntegrationTest.cpp +++ b/tests/aws-cpp-sdk-dynamodb-integration-tests/ScanPaginationIntegrationTest.cpp @@ -78,9 +78,9 @@ class ScanPaginationTest : public Aws::Testing::AwsCppSdkGTestSuite { WaitUntilActive(tableName); } - DescribeTableResult WaitUntilActive(const Aws::String& tableName) { + DescribeTableResult WaitUntilActive(const Aws::String& tableNameParam) { DescribeTableRequest describeTableRequest; - describeTableRequest.SetTableName(tableName); + describeTableRequest.SetTableName(tableNameParam); DescribeTableOutcome outcome = dynamoClient->DescribeTable(describeTableRequest); while (outcome.IsSuccess() && outcome.GetResult().GetTable().GetTableStatus() != TableStatus::ACTIVE) { From a501c29ffe6f5d2d917a0130f86f991eb5b56ce8 Mon Sep 17 00:00:00 2001 From: kai lin Date: Thu, 22 Jan 2026 18:48:18 -0500 Subject: [PATCH 37/46] literally copy bucket integration test --- ...ListObjectsV2PaginationIntegrationTest.cpp | 166 +++++++++++++----- 1 file changed, 126 insertions(+), 40 deletions(-) diff --git a/tests/aws-cpp-sdk-s3-integration-tests/ListObjectsV2PaginationIntegrationTest.cpp b/tests/aws-cpp-sdk-s3-integration-tests/ListObjectsV2PaginationIntegrationTest.cpp index 1f345d53b2d5..1e2bca8bf450 100644 --- a/tests/aws-cpp-sdk-s3-integration-tests/ListObjectsV2PaginationIntegrationTest.cpp +++ b/tests/aws-cpp-sdk-s3-integration-tests/ListObjectsV2PaginationIntegrationTest.cpp @@ -1,20 +1,23 @@ -/* +/** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ #include +#include +#include #include -#include +#include #include #include #include +#include #include #include #include #include -#include -#include +#include +#include using namespace Aws; using namespace Aws::S3; @@ -22,30 +25,44 @@ using namespace Aws::S3::Model; namespace { static const char* ALLOCATION_TAG = "ListObjectsV2PaginationTest"; + static const char* TEST_BUCKET_TAG = "IntegrationTestResource"; + static const int TIMEOUT_MAX = 20; const size_t OBJECT_COUNT = 15; const size_t MAX_KEYS = 3; } class ListObjectsV2PaginationTest : public Aws::Testing::AwsCppSdkGTestSuite { protected: - std::shared_ptr s3Client; + std::shared_ptr Client; Aws::String bucketName; Aws::String emptyBucketName; void SetUp() override { - Aws::SDKOptions options; - Aws::InitAPI(options); + Aws::Client::ClientConfiguration config; + config.region = Aws::Region::US_EAST_1; + config.scheme = Aws::Http::Scheme::HTTPS; + config.connectTimeoutMs = 30000; + config.requestTimeoutMs = 30000; - s3Client = Aws::MakeShared(ALLOCATION_TAG); + Client = Aws::MakeShared(ALLOCATION_TAG, config); + bucketName = CalculateBucketName("listobjectsv2paginationtest"); emptyBucketName = CalculateBucketName("listobjectsv2emptytest"); CreateBucketRequest createRequest; createRequest.SetBucket(bucketName); - s3Client->CreateBucket(createRequest); + createRequest.SetACL(BucketCannedACL::private_); + auto createOutcome = Client->CreateBucket(createRequest); + AWS_ASSERT_SUCCESS(createOutcome); createRequest.SetBucket(emptyBucketName); - s3Client->CreateBucket(createRequest); + createOutcome = Client->CreateBucket(createRequest); + AWS_ASSERT_SUCCESS(createOutcome); + + ASSERT_TRUE(WaitForBucketToPropagate(bucketName)); + ASSERT_TRUE(WaitForBucketToPropagate(emptyBucketName)); + TagTestBucket(bucketName); + TagTestBucket(emptyBucketName); // Create test objects for (size_t i = 1; i <= OBJECT_COUNT; ++i) { @@ -56,31 +73,99 @@ class ListObjectsV2PaginationTest : public Aws::Testing::AwsCppSdkGTestSuite { } void TearDown() override { - // Delete all objects - ListObjectsV2Request listRequest; - listRequest.SetBucket(bucketName); - auto listOutcome = s3Client->ListObjectsV2(listRequest); - if (listOutcome.IsSuccess()) { - for (const auto& object : listOutcome.GetResult().GetContents()) { - DeleteObjectRequest deleteRequest; - deleteRequest.SetBucket(bucketName); - deleteRequest.SetKey(object.GetKey()); - s3Client->DeleteObject(deleteRequest); + DeleteBucket(bucketName); + DeleteBucket(emptyBucketName); + Client = nullptr; + } + + static void TagTestBucket(const Aws::String& bucketName, const std::shared_ptr& client) { + ASSERT_TRUE(!bucketName.empty()); + ASSERT_TRUE(client); + + PutBucketTaggingRequest taggingRequest; + taggingRequest.SetBucket(bucketName); + Tag tag; + tag.SetKey(TEST_BUCKET_TAG); + tag.SetValue(TEST_BUCKET_TAG); + Tagging tagging; + tagging.AddTagSet(tag); + taggingRequest.SetTagging(tagging); + + auto taggingOutcome = client->PutBucketTagging(taggingRequest); + AWS_ASSERT_SUCCESS(taggingOutcome); + } + + void TagTestBucket(const Aws::String& bucketNameParam) { + TagTestBucket(bucketNameParam, Client); + } + + bool WaitForBucketToPropagate(const Aws::String& bucketNameParam) { + unsigned timeoutCount = 0; + while (timeoutCount++ < TIMEOUT_MAX) { + ListObjectsV2Request listRequest; + listRequest.SetBucket(bucketNameParam); + auto listOutcome = Client->ListObjectsV2(listRequest); + if (listOutcome.IsSuccess()) { + return true; } + std::this_thread::sleep_for(std::chrono::seconds(10)); + } + return false; + } + + void EmptyBucket(const Aws::String& bucketNameParam) { + ListObjectsV2Request listObjectsRequest; + listObjectsRequest.SetBucket(bucketNameParam); + + ListObjectsV2Outcome listObjectsOutcome = Client->ListObjectsV2(listObjectsRequest); + + if (!listObjectsOutcome.IsSuccess()) + return; + + for (const auto& object : listObjectsOutcome.GetResult().GetContents()) { + DeleteObjectRequest deleteObjectRequest; + deleteObjectRequest.SetBucket(bucketNameParam); + deleteObjectRequest.SetKey(object.GetKey()); + auto deleteObjectOutcome = Client->DeleteObject(deleteObjectRequest); + AWS_ASSERT_SUCCESS(deleteObjectOutcome); + } + } + + void WaitForBucketToEmpty(const Aws::String& bucketNameParam) { + ListObjectsV2Request listObjectsRequest; + listObjectsRequest.SetBucket(bucketNameParam); + + unsigned checkForObjectsCount = 0; + while (checkForObjectsCount++ < TIMEOUT_MAX) { + ListObjectsV2Outcome listObjectsOutcome = Client->ListObjectsV2(listObjectsRequest); + AWS_EXPECT_SUCCESS(listObjectsOutcome); + + if (listObjectsOutcome.GetResult().GetContents().size() > 0) { + std::this_thread::sleep_for(std::chrono::seconds(5)); + } else { + break; + } + } + } + + void DeleteBucket(const Aws::String& bucketNameParam) { + HeadBucketRequest headBucketRequest; + headBucketRequest.SetBucket(bucketNameParam); + HeadBucketOutcome bucketOutcome = Client->HeadBucket(headBucketRequest); + + if (bucketOutcome.IsSuccess()) { + EmptyBucket(bucketNameParam); + WaitForBucketToEmpty(bucketNameParam); + + DeleteBucketRequest deleteBucketRequest; + deleteBucketRequest.SetBucket(bucketNameParam); + + DeleteBucketOutcome deleteBucketOutcome = Client->DeleteBucket(deleteBucketRequest); + AWS_EXPECT_SUCCESS(deleteBucketOutcome); } - - DeleteBucketRequest deleteRequest; - deleteRequest.SetBucket(bucketName); - s3Client->DeleteBucket(deleteRequest); - - deleteRequest.SetBucket(emptyBucketName); - s3Client->DeleteBucket(deleteRequest); - - Aws::SDKOptions options; - Aws::ShutdownAPI(options); } - Aws::String CalculateBucketName(const Aws::String& bucketPrefix) { + static Aws::String CalculateBucketName(const Aws::String& bucketPrefix) { return Aws::Testing::GetAwsResourcePrefix() + bucketPrefix; } @@ -93,7 +178,8 @@ class ListObjectsV2PaginationTest : public Aws::Testing::AwsCppSdkGTestSuite { *data << "Test data for " << key; putRequest.SetBody(data); - s3Client->PutObject(putRequest); + auto putOutcome = Client->PutObject(putRequest); + AWS_ASSERT_SUCCESS(putOutcome); } }; @@ -103,7 +189,7 @@ TEST_F(ListObjectsV2PaginationTest, TestPaginationOnEmptyBucket) { request.SetMaxKeys(MAX_KEYS); size_t objectCount = 0; - auto outcome = s3Client->ListObjectsV2(request); + auto outcome = Client->ListObjectsV2(request); while (outcome.IsSuccess()) { const auto& result = outcome.GetResult(); @@ -114,10 +200,10 @@ TEST_F(ListObjectsV2PaginationTest, TestPaginationOnEmptyBucket) { } Aws::S3::Pagination::ListObjectsV2PaginationTraits::SetNextRequest(result, request); - outcome = s3Client->ListObjectsV2(request); + outcome = Client->ListObjectsV2(request); } - ASSERT_TRUE(outcome.IsSuccess()); + AWS_ASSERT_SUCCESS(outcome); EXPECT_EQ(0u, objectCount); } @@ -128,7 +214,7 @@ TEST_F(ListObjectsV2PaginationTest, TestPaginationOnNonEmptyBucket) { size_t objectCount = 0; size_t pageCount = 0; - auto outcome = s3Client->ListObjectsV2(request); + auto outcome = Client->ListObjectsV2(request); while (outcome.IsSuccess()) { const auto& result = outcome.GetResult(); @@ -140,10 +226,10 @@ TEST_F(ListObjectsV2PaginationTest, TestPaginationOnNonEmptyBucket) { } Aws::S3::Pagination::ListObjectsV2PaginationTraits::SetNextRequest(result, request); - outcome = s3Client->ListObjectsV2(request); + outcome = Client->ListObjectsV2(request); } - ASSERT_TRUE(outcome.IsSuccess()); + AWS_ASSERT_SUCCESS(outcome); EXPECT_EQ(OBJECT_COUNT, objectCount); EXPECT_GT(pageCount, 1u); // Should have multiple pages with MaxKeys=3 } @@ -156,8 +242,8 @@ TEST_F(ListObjectsV2PaginationTest, TestManualPaginationLoop) { Aws::Vector allKeys; do { - auto outcome = s3Client->ListObjectsV2(request); - ASSERT_TRUE(outcome.IsSuccess()); + auto outcome = Client->ListObjectsV2(request); + AWS_ASSERT_SUCCESS(outcome); const auto& result = outcome.GetResult(); for (const auto& object : result.GetContents()) { From b9aa80cf6a1c6d35b2d9d713c8038bc43c57cca0 Mon Sep 17 00:00:00 2001 From: kai lin Date: Tue, 27 Jan 2026 16:09:15 -0500 Subject: [PATCH 38/46] updated codegen for c2j client to use CRTP base clients that have methods for pagination, and smithy generator to make the base client templates. comment out the integration test. move the model traits into the service model dir instead of pagination dir --- .../include/aws/dynamodb/DynamoDBClient.h | 4 +- .../aws/dynamodb/DynamoDBClientPagination.h | 31 + .../aws/dynamodb/DynamoDBPaginationBase.h | 83 + .../{pagination => }/ScanPaginationTraits.h | 8 +- .../include/aws/ec2/EC2Client.h | 5 +- .../include/aws/ec2/EC2ClientPagination.h | 592 +++++ .../include/aws/ec2/EC2PaginationBase.h | 1944 +++++++++++++++++ ...DescribeSpotPriceHistoryPaginationTraits.h | 8 +- .../aws-cpp-sdk-s3/include/aws/s3/S3Client.h | 5 +- .../include/aws/s3/S3ClientPagination.h | 8 +- .../include/aws/s3/S3PaginationBase.h | 62 + .../ListBucketsPaginationTraits.h | 8 +- .../ListDirectoryBucketsPaginationTraits.h | 8 +- .../ListObjectsV2PaginationTraits.h | 8 +- .../ListPartsPaginationTraits.h | 8 +- .../DynamoDBPaginationCompilationTests.cpp | 13 +- .../EC2PaginationCompilationTests.cpp | 327 +-- .../S3PaginationCompilationTests.cpp | 9 +- .../ScanPaginationIntegrationTest.cpp | 7 +- .../EC2PaginationIntegrationTest.cpp | 6 +- ...ListObjectsV2PaginationIntegrationTest.cpp | 5 +- .../cpp/json/JsonServiceClientHeader.vm | 3 +- .../velocity/cpp/s3/S3ClientHeader.vm | 3 +- .../velocity/cpp/smithy/SmithyClientHeader.vm | 4 +- .../cpp/xml/XmlServiceClientHeader.vm | 3 +- .../templates/PaginationBaseGenerator.java | 96 + .../PaginationClientHeaderGenerator.java | 2 +- .../templates/PaginationCodegenPlugin.java | 7 + .../PaginationCompilationTestGenerator.java | 11 +- .../templates/PaginationTraitsGenerator.java | 13 +- .../codegen/cpp-pagination/smithy-build.json | 150 -- 31 files changed, 3084 insertions(+), 357 deletions(-) create mode 100644 generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClientPagination.h create mode 100644 generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBPaginationBase.h rename generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/model/{pagination => }/ScanPaginationTraits.h (78%) create mode 100644 generated/src/aws-cpp-sdk-ec2/include/aws/ec2/EC2ClientPagination.h create mode 100644 generated/src/aws-cpp-sdk-ec2/include/aws/ec2/EC2PaginationBase.h rename generated/src/aws-cpp-sdk-ec2/include/aws/ec2/model/{pagination => }/DescribeSpotPriceHistoryPaginationTraits.h (79%) create mode 100644 generated/src/aws-cpp-sdk-s3/include/aws/s3/S3PaginationBase.h rename generated/src/aws-cpp-sdk-s3/include/aws/s3/model/{pagination => }/ListBucketsPaginationTraits.h (79%) rename generated/src/aws-cpp-sdk-s3/include/aws/s3/model/{pagination => }/ListDirectoryBucketsPaginationTraits.h (79%) rename generated/src/aws-cpp-sdk-s3/include/aws/s3/model/{pagination => }/ListObjectsV2PaginationTraits.h (79%) rename generated/src/aws-cpp-sdk-s3/include/aws/s3/model/{pagination => }/ListPartsPaginationTraits.h (79%) create mode 100644 tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationBaseGenerator.java diff --git a/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h index 873154dd938b..a4cfb576b72e 100644 --- a/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h +++ b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClient.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -40,7 +41,8 @@ class AWS_DYNAMODB_API DynamoDBClient public smithy::client::AwsSmithyClientT, Aws::Crt::Variant, DynamoDBEndpointProviderBase, smithy::client::JsonOutcomeSerializer, - smithy::client::JsonOutcome, Aws::Client::DynamoDBErrorMarshaller> { + smithy::client::JsonOutcome, Aws::Client::DynamoDBErrorMarshaller>, + public DynamoDBPaginationBase { public: static const char* GetServiceName(); static const char* GetAllocationTag(); diff --git a/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClientPagination.h b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClientPagination.h new file mode 100644 index 000000000000..41e75132dbc4 --- /dev/null +++ b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBClientPagination.h @@ -0,0 +1,31 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Aws { +namespace DynamoDB { + +using ListContributorInsightsPaginator = Aws::Utils::Pagination::PagePaginator; +using ListExportsPaginator = + Aws::Utils::Pagination::PagePaginator; +using ListImportsPaginator = + Aws::Utils::Pagination::PagePaginator; +using ListTablesPaginator = + Aws::Utils::Pagination::PagePaginator; +using QueryPaginator = Aws::Utils::Pagination::PagePaginator; +using ScanPaginator = Aws::Utils::Pagination::PagePaginator; + +} // namespace DynamoDB +} // namespace Aws diff --git a/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBPaginationBase.h b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBPaginationBase.h new file mode 100644 index 000000000000..739b15e86c26 --- /dev/null +++ b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/DynamoDBPaginationBase.h @@ -0,0 +1,83 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace Aws { +namespace DynamoDB { + +class DynamoDBClient; + +template +class DynamoDBPaginationBase { + public: + /** + * Create a paginator for ListContributorInsights operation + */ + Aws::Utils::Pagination::PagePaginator + ListContributorInsightsPaginator(const Model::ListContributorInsightsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for ListExports operation + */ + Aws::Utils::Pagination::PagePaginator + ListExportsPaginator(const Model::ListExportsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for ListImports operation + */ + Aws::Utils::Pagination::PagePaginator + ListImportsPaginator(const Model::ListImportsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for ListTables operation + */ + Aws::Utils::Pagination::PagePaginator + ListTablesPaginator(const Model::ListTablesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for Query operation + */ + Aws::Utils::Pagination::PagePaginator QueryPaginator( + const Model::QueryRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for Scan operation + */ + Aws::Utils::Pagination::PagePaginator ScanPaginator( + const Model::ScanRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } +}; +} // namespace DynamoDB +} // namespace Aws diff --git a/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/model/pagination/ScanPaginationTraits.h b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/model/ScanPaginationTraits.h similarity index 78% rename from generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/model/pagination/ScanPaginationTraits.h rename to generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/model/ScanPaginationTraits.h index 0cd157c097ec..988cf65a5828 100644 --- a/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/model/pagination/ScanPaginationTraits.h +++ b/generated/src/aws-cpp-sdk-dynamodb/include/aws/dynamodb/model/ScanPaginationTraits.h @@ -4,13 +4,14 @@ */ #pragma once -#include +#include #include #include #include namespace Aws { namespace DynamoDB { +class DynamoDBClient; namespace Pagination { struct ScanPaginationTraits { @@ -19,7 +20,10 @@ struct ScanPaginationTraits { using OutcomeType = Model::ScanOutcome; using ClientType = DynamoDBClient; - static OutcomeType Invoke(ClientType& client, const RequestType& request) { return client.Scan(request); } + template + static OutcomeType Invoke(Client& client, const RequestType& request) { + return client.Scan(request); + } static bool HasMoreResults(const ResultType& result) { return !result.GetLastEvaluatedKey().empty(); } diff --git a/generated/src/aws-cpp-sdk-ec2/include/aws/ec2/EC2Client.h b/generated/src/aws-cpp-sdk-ec2/include/aws/ec2/EC2Client.h index 448f1a952f35..49cf8ca71505 100644 --- a/generated/src/aws-cpp-sdk-ec2/include/aws/ec2/EC2Client.h +++ b/generated/src/aws-cpp-sdk-ec2/include/aws/ec2/EC2Client.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -21,7 +22,9 @@ namespace EC2 { * href="https://docs.aws.amazon.com/ec2/latest/devguide">Amazon EC2 Developer * Guide.

*/ -class AWS_EC2_API EC2Client : public Aws::Client::AWSXMLClient, public Aws::Client::ClientWithAsyncTemplateMethods { +class AWS_EC2_API EC2Client : public Aws::Client::AWSXMLClient, + public Aws::Client::ClientWithAsyncTemplateMethods, + public EC2PaginationBase { public: typedef Aws::Client::AWSXMLClient BASECLASS; static const char* GetServiceName(); diff --git a/generated/src/aws-cpp-sdk-ec2/include/aws/ec2/EC2ClientPagination.h b/generated/src/aws-cpp-sdk-ec2/include/aws/ec2/EC2ClientPagination.h new file mode 100644 index 000000000000..a108d6a661d3 --- /dev/null +++ b/generated/src/aws-cpp-sdk-ec2/include/aws/ec2/EC2ClientPagination.h @@ -0,0 +1,592 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Aws { +namespace EC2 { + +using DescribeAddressesAttributePaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeAddressTransfersPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeAwsNetworkPerformanceMetricSubscriptionsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeByoipCidrsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeCapacityBlockExtensionHistoryPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeCapacityBlockExtensionOfferingsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeCapacityBlockOfferingsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeCapacityBlocksPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeCapacityBlockStatusPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeCapacityManagerDataExportsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeCapacityReservationBillingRequestsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeCapacityReservationFleetsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeCapacityReservationsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeCarrierGatewaysPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeClassicLinkInstancesPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeClientVpnAuthorizationRulesPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeClientVpnConnectionsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeClientVpnEndpointsPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeClientVpnRoutesPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeClientVpnTargetNetworksPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeCoipPoolsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeDhcpOptionsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeEgressOnlyInternetGatewaysPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeExportImageTasksPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeFastLaunchImagesPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeFastSnapshotRestoresPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeFleetsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeFlowLogsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeFpgaImagesPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeHostReservationOfferingsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeHostReservationsPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeHostsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeIamInstanceProfileAssociationsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeImageReferencesPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeImagesPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeImageUsageReportEntriesPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeImageUsageReportsPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeImportImageTasksPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeImportSnapshotTasksPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeInstanceConnectEndpointsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeInstanceCreditSpecificationsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeInstanceEventWindowsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeInstanceImageMetadataPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeInstancesPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeInstanceStatusPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeInstanceTopologyPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeInstanceTypeOfferingsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeInstanceTypesPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeInternetGatewaysPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeIpamPoolsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeIpamPrefixListResolversPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeIpamPrefixListResolverTargetsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeIpamResourceDiscoveriesPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeIpamResourceDiscoveryAssociationsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeIpamsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeIpamScopesPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeIpv6PoolsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeLaunchTemplatesPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeLaunchTemplateVersionsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeLocalGatewayRouteTablesPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeLocalGatewayRouteTableVirtualInterfaceGroupAssociationsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeLocalGatewayRouteTableVpcAssociationsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeLocalGatewaysPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeLocalGatewayVirtualInterfaceGroupsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeLocalGatewayVirtualInterfacesPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeMacHostsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeMacModificationTasksPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeManagedPrefixListsPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeMovingAddressesPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeNatGatewaysPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeNetworkAclsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeNetworkInsightsAccessScopeAnalysesPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeNetworkInsightsAccessScopesPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeNetworkInsightsAnalysesPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeNetworkInsightsPathsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeNetworkInterfacePermissionsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeNetworkInterfacesPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribePrefixListsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribePrincipalIdFormatPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribePublicIpv4PoolsPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeReplaceRootVolumeTasksPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeReservedInstancesModificationsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeReservedInstancesOfferingsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeRouteServerEndpointsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeRouteServerPeersPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeRouteServersPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeRouteTablesPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeScheduledInstanceAvailabilityPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeScheduledInstancesPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeSecurityGroupRulesPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeSecurityGroupsPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeSecurityGroupVpcAssociationsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeSnapshotsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeSnapshotTierStatusPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeSpotFleetRequestsPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeSpotInstanceRequestsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeSpotPriceHistoryPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeStaleSecurityGroupsPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeStoreImageTasksPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeSubnetsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeTagsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeTrafficMirrorFiltersPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeTrafficMirrorSessionsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeTrafficMirrorTargetsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeTransitGatewayAttachmentsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeTransitGatewayConnectPeersPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeTransitGatewayConnectsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeTransitGatewayMulticastDomainsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeTransitGatewayPeeringAttachmentsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeTransitGatewayPolicyTablesPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeTransitGatewayRouteTableAnnouncementsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeTransitGatewayRouteTablesPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeTransitGatewaysPaginator = Aws::Utils::Pagination::PagePaginator; +using DescribeTransitGatewayVpcAttachmentsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeTrunkInterfaceAssociationsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeVerifiedAccessEndpointsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeVerifiedAccessGroupsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeVerifiedAccessInstanceLoggingConfigurationsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeVerifiedAccessInstancesPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeVerifiedAccessTrustProvidersPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeVolumesPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeVolumesModificationsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeVolumeStatusPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeVpcClassicLinkDnsSupportPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeVpcEndpointConnectionNotificationsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeVpcEndpointConnectionsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeVpcEndpointsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeVpcEndpointServiceConfigurationsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeVpcEndpointServicePermissionsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeVpcPeeringConnectionsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeVpcsPaginator = + Aws::Utils::Pagination::PagePaginator; +using DescribeVpnConcentratorsPaginator = Aws::Utils::Pagination::PagePaginator; +using GetAssociatedIpv6PoolCidrsPaginator = Aws::Utils::Pagination::PagePaginator; +using GetAwsNetworkPerformanceDataPaginator = + Aws::Utils::Pagination::PagePaginator; +using GetCapacityManagerMetricDataPaginator = + Aws::Utils::Pagination::PagePaginator; +using GetCapacityManagerMetricDimensionsPaginator = + Aws::Utils::Pagination::PagePaginator; +using GetGroupsForCapacityReservationPaginator = + Aws::Utils::Pagination::PagePaginator; +using GetInstanceTypesFromInstanceRequirementsPaginator = + Aws::Utils::Pagination::PagePaginator; +using GetIpamAddressHistoryPaginator = Aws::Utils::Pagination::PagePaginator; +using GetIpamDiscoveredAccountsPaginator = Aws::Utils::Pagination::PagePaginator; +using GetIpamDiscoveredResourceCidrsPaginator = + Aws::Utils::Pagination::PagePaginator; +using GetIpamPoolAllocationsPaginator = Aws::Utils::Pagination::PagePaginator; +using GetIpamPoolCidrsPaginator = + Aws::Utils::Pagination::PagePaginator; +using GetIpamPrefixListResolverRulesPaginator = + Aws::Utils::Pagination::PagePaginator; +using GetIpamPrefixListResolverVersionEntriesPaginator = + Aws::Utils::Pagination::PagePaginator; +using GetIpamPrefixListResolverVersionsPaginator = + Aws::Utils::Pagination::PagePaginator; +using GetIpamResourceCidrsPaginator = + Aws::Utils::Pagination::PagePaginator; +using GetManagedPrefixListAssociationsPaginator = + Aws::Utils::Pagination::PagePaginator; +using GetManagedPrefixListEntriesPaginator = Aws::Utils::Pagination::PagePaginator; +using GetNetworkInsightsAccessScopeAnalysisFindingsPaginator = + Aws::Utils::Pagination::PagePaginator; +using GetSecurityGroupsForVpcPaginator = Aws::Utils::Pagination::PagePaginator; +using GetSpotPlacementScoresPaginator = Aws::Utils::Pagination::PagePaginator; +using GetTransitGatewayAttachmentPropagationsPaginator = + Aws::Utils::Pagination::PagePaginator; +using GetTransitGatewayMulticastDomainAssociationsPaginator = + Aws::Utils::Pagination::PagePaginator; +using GetTransitGatewayPolicyTableAssociationsPaginator = + Aws::Utils::Pagination::PagePaginator; +using GetTransitGatewayPrefixListReferencesPaginator = + Aws::Utils::Pagination::PagePaginator; +using GetTransitGatewayRouteTableAssociationsPaginator = + Aws::Utils::Pagination::PagePaginator; +using GetTransitGatewayRouteTablePropagationsPaginator = + Aws::Utils::Pagination::PagePaginator; +using GetVpnConnectionDeviceTypesPaginator = Aws::Utils::Pagination::PagePaginator; +using ListImagesInRecycleBinPaginator = Aws::Utils::Pagination::PagePaginator; +using ListSnapshotsInRecycleBinPaginator = Aws::Utils::Pagination::PagePaginator; +using SearchLocalGatewayRoutesPaginator = Aws::Utils::Pagination::PagePaginator; +using SearchTransitGatewayMulticastGroupsPaginator = + Aws::Utils::Pagination::PagePaginator; + +} // namespace EC2 +} // namespace Aws diff --git a/generated/src/aws-cpp-sdk-ec2/include/aws/ec2/EC2PaginationBase.h b/generated/src/aws-cpp-sdk-ec2/include/aws/ec2/EC2PaginationBase.h new file mode 100644 index 000000000000..da4d9f967f4f --- /dev/null +++ b/generated/src/aws-cpp-sdk-ec2/include/aws/ec2/EC2PaginationBase.h @@ -0,0 +1,1944 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace Aws { +namespace EC2 { + +class EC2Client; + +template +class EC2PaginationBase { + public: + /** + * Create a paginator for DescribeAddressesAttribute operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeAddressesAttributePaginator(const Model::DescribeAddressesAttributeRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeAddressTransfers operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeAddressTransfersPaginator(const Model::DescribeAddressTransfersRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeAwsNetworkPerformanceMetricSubscriptions operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeAwsNetworkPerformanceMetricSubscriptionsPaginator(const Model::DescribeAwsNetworkPerformanceMetricSubscriptionsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeByoipCidrs operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeByoipCidrsPaginator(const Model::DescribeByoipCidrsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeCapacityBlockExtensionHistory operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeCapacityBlockExtensionHistoryPaginator(const Model::DescribeCapacityBlockExtensionHistoryRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeCapacityBlockExtensionOfferings operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeCapacityBlockExtensionOfferingsPaginator(const Model::DescribeCapacityBlockExtensionOfferingsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeCapacityBlockOfferings operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeCapacityBlockOfferingsPaginator(const Model::DescribeCapacityBlockOfferingsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeCapacityBlocks operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeCapacityBlocksPaginator(const Model::DescribeCapacityBlocksRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeCapacityBlockStatus operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeCapacityBlockStatusPaginator(const Model::DescribeCapacityBlockStatusRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeCapacityManagerDataExports operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeCapacityManagerDataExportsPaginator(const Model::DescribeCapacityManagerDataExportsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeCapacityReservationBillingRequests operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeCapacityReservationBillingRequestsPaginator(const Model::DescribeCapacityReservationBillingRequestsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeCapacityReservationFleets operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeCapacityReservationFleetsPaginator(const Model::DescribeCapacityReservationFleetsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeCapacityReservations operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeCapacityReservationsPaginator(const Model::DescribeCapacityReservationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeCarrierGateways operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeCarrierGatewaysPaginator(const Model::DescribeCarrierGatewaysRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeClassicLinkInstances operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeClassicLinkInstancesPaginator(const Model::DescribeClassicLinkInstancesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeClientVpnAuthorizationRules operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeClientVpnAuthorizationRulesPaginator(const Model::DescribeClientVpnAuthorizationRulesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeClientVpnConnections operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeClientVpnConnectionsPaginator(const Model::DescribeClientVpnConnectionsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeClientVpnEndpoints operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeClientVpnEndpointsPaginator(const Model::DescribeClientVpnEndpointsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeClientVpnRoutes operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeClientVpnRoutesPaginator(const Model::DescribeClientVpnRoutesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeClientVpnTargetNetworks operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeClientVpnTargetNetworksPaginator(const Model::DescribeClientVpnTargetNetworksRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeCoipPools operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeCoipPoolsPaginator(const Model::DescribeCoipPoolsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeDhcpOptions operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeDhcpOptionsPaginator(const Model::DescribeDhcpOptionsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeEgressOnlyInternetGateways operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeEgressOnlyInternetGatewaysPaginator(const Model::DescribeEgressOnlyInternetGatewaysRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeExportImageTasks operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeExportImageTasksPaginator(const Model::DescribeExportImageTasksRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeFastLaunchImages operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeFastLaunchImagesPaginator(const Model::DescribeFastLaunchImagesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeFastSnapshotRestores operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeFastSnapshotRestoresPaginator(const Model::DescribeFastSnapshotRestoresRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeFleets operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeFleetsPaginator(const Model::DescribeFleetsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeFlowLogs operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeFlowLogsPaginator(const Model::DescribeFlowLogsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeFpgaImages operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeFpgaImagesPaginator(const Model::DescribeFpgaImagesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeHostReservationOfferings operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeHostReservationOfferingsPaginator(const Model::DescribeHostReservationOfferingsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeHostReservations operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeHostReservationsPaginator(const Model::DescribeHostReservationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeHosts operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeHostsPaginator(const Model::DescribeHostsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeIamInstanceProfileAssociations operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeIamInstanceProfileAssociationsPaginator(const Model::DescribeIamInstanceProfileAssociationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeImageReferences operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeImageReferencesPaginator(const Model::DescribeImageReferencesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeImages operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeImagesPaginator(const Model::DescribeImagesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeImageUsageReportEntries operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeImageUsageReportEntriesPaginator(const Model::DescribeImageUsageReportEntriesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeImageUsageReports operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeImageUsageReportsPaginator(const Model::DescribeImageUsageReportsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeImportImageTasks operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeImportImageTasksPaginator(const Model::DescribeImportImageTasksRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeImportSnapshotTasks operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeImportSnapshotTasksPaginator(const Model::DescribeImportSnapshotTasksRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeInstanceConnectEndpoints operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeInstanceConnectEndpointsPaginator(const Model::DescribeInstanceConnectEndpointsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeInstanceCreditSpecifications operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeInstanceCreditSpecificationsPaginator(const Model::DescribeInstanceCreditSpecificationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeInstanceEventWindows operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeInstanceEventWindowsPaginator(const Model::DescribeInstanceEventWindowsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeInstanceImageMetadata operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeInstanceImageMetadataPaginator(const Model::DescribeInstanceImageMetadataRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeInstances operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeInstancesPaginator(const Model::DescribeInstancesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeInstanceStatus operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeInstanceStatusPaginator(const Model::DescribeInstanceStatusRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeInstanceTopology operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeInstanceTopologyPaginator(const Model::DescribeInstanceTopologyRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeInstanceTypeOfferings operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeInstanceTypeOfferingsPaginator(const Model::DescribeInstanceTypeOfferingsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeInstanceTypes operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeInstanceTypesPaginator(const Model::DescribeInstanceTypesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeInternetGateways operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeInternetGatewaysPaginator(const Model::DescribeInternetGatewaysRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeIpamPools operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeIpamPoolsPaginator(const Model::DescribeIpamPoolsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeIpamPrefixListResolvers operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeIpamPrefixListResolversPaginator(const Model::DescribeIpamPrefixListResolversRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeIpamPrefixListResolverTargets operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeIpamPrefixListResolverTargetsPaginator(const Model::DescribeIpamPrefixListResolverTargetsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeIpamResourceDiscoveries operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeIpamResourceDiscoveriesPaginator(const Model::DescribeIpamResourceDiscoveriesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeIpamResourceDiscoveryAssociations operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeIpamResourceDiscoveryAssociationsPaginator(const Model::DescribeIpamResourceDiscoveryAssociationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeIpams operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeIpamsPaginator(const Model::DescribeIpamsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeIpamScopes operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeIpamScopesPaginator(const Model::DescribeIpamScopesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeIpv6Pools operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeIpv6PoolsPaginator(const Model::DescribeIpv6PoolsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeLaunchTemplates operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeLaunchTemplatesPaginator(const Model::DescribeLaunchTemplatesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeLaunchTemplateVersions operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeLaunchTemplateVersionsPaginator(const Model::DescribeLaunchTemplateVersionsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeLocalGatewayRouteTables operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeLocalGatewayRouteTablesPaginator(const Model::DescribeLocalGatewayRouteTablesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeLocalGatewayRouteTableVirtualInterfaceGroupAssociations operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeLocalGatewayRouteTableVirtualInterfaceGroupAssociationsPaginator( + const Model::DescribeLocalGatewayRouteTableVirtualInterfaceGroupAssociationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator< + DerivedClient, Model::DescribeLocalGatewayRouteTableVirtualInterfaceGroupAssociationsRequest, + Pagination::DescribeLocalGatewayRouteTableVirtualInterfaceGroupAssociationsPaginationTraits>{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeLocalGatewayRouteTableVpcAssociations operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeLocalGatewayRouteTableVpcAssociationsPaginator(const Model::DescribeLocalGatewayRouteTableVpcAssociationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeLocalGateways operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeLocalGatewaysPaginator(const Model::DescribeLocalGatewaysRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeLocalGatewayVirtualInterfaceGroups operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeLocalGatewayVirtualInterfaceGroupsPaginator(const Model::DescribeLocalGatewayVirtualInterfaceGroupsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeLocalGatewayVirtualInterfaces operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeLocalGatewayVirtualInterfacesPaginator(const Model::DescribeLocalGatewayVirtualInterfacesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeMacHosts operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeMacHostsPaginator(const Model::DescribeMacHostsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeMacModificationTasks operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeMacModificationTasksPaginator(const Model::DescribeMacModificationTasksRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeManagedPrefixLists operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeManagedPrefixListsPaginator(const Model::DescribeManagedPrefixListsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeMovingAddresses operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeMovingAddressesPaginator(const Model::DescribeMovingAddressesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeNatGateways operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeNatGatewaysPaginator(const Model::DescribeNatGatewaysRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeNetworkAcls operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeNetworkAclsPaginator(const Model::DescribeNetworkAclsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeNetworkInsightsAccessScopeAnalyses operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeNetworkInsightsAccessScopeAnalysesPaginator(const Model::DescribeNetworkInsightsAccessScopeAnalysesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeNetworkInsightsAccessScopes operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeNetworkInsightsAccessScopesPaginator(const Model::DescribeNetworkInsightsAccessScopesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeNetworkInsightsAnalyses operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeNetworkInsightsAnalysesPaginator(const Model::DescribeNetworkInsightsAnalysesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeNetworkInsightsPaths operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeNetworkInsightsPathsPaginator(const Model::DescribeNetworkInsightsPathsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeNetworkInterfacePermissions operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeNetworkInterfacePermissionsPaginator(const Model::DescribeNetworkInterfacePermissionsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeNetworkInterfaces operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeNetworkInterfacesPaginator(const Model::DescribeNetworkInterfacesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribePrefixLists operation + */ + Aws::Utils::Pagination::PagePaginator + DescribePrefixListsPaginator(const Model::DescribePrefixListsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribePrincipalIdFormat operation + */ + Aws::Utils::Pagination::PagePaginator + DescribePrincipalIdFormatPaginator(const Model::DescribePrincipalIdFormatRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribePublicIpv4Pools operation + */ + Aws::Utils::Pagination::PagePaginator + DescribePublicIpv4PoolsPaginator(const Model::DescribePublicIpv4PoolsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeReplaceRootVolumeTasks operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeReplaceRootVolumeTasksPaginator(const Model::DescribeReplaceRootVolumeTasksRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeReservedInstancesModifications operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeReservedInstancesModificationsPaginator(const Model::DescribeReservedInstancesModificationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeReservedInstancesOfferings operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeReservedInstancesOfferingsPaginator(const Model::DescribeReservedInstancesOfferingsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeRouteServerEndpoints operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeRouteServerEndpointsPaginator(const Model::DescribeRouteServerEndpointsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeRouteServerPeers operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeRouteServerPeersPaginator(const Model::DescribeRouteServerPeersRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeRouteServers operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeRouteServersPaginator(const Model::DescribeRouteServersRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeRouteTables operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeRouteTablesPaginator(const Model::DescribeRouteTablesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeScheduledInstanceAvailability operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeScheduledInstanceAvailabilityPaginator(const Model::DescribeScheduledInstanceAvailabilityRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeScheduledInstances operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeScheduledInstancesPaginator(const Model::DescribeScheduledInstancesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeSecurityGroupRules operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeSecurityGroupRulesPaginator(const Model::DescribeSecurityGroupRulesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeSecurityGroups operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeSecurityGroupsPaginator(const Model::DescribeSecurityGroupsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeSecurityGroupVpcAssociations operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeSecurityGroupVpcAssociationsPaginator(const Model::DescribeSecurityGroupVpcAssociationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeSnapshots operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeSnapshotsPaginator(const Model::DescribeSnapshotsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeSnapshotTierStatus operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeSnapshotTierStatusPaginator(const Model::DescribeSnapshotTierStatusRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeSpotFleetRequests operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeSpotFleetRequestsPaginator(const Model::DescribeSpotFleetRequestsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeSpotInstanceRequests operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeSpotInstanceRequestsPaginator(const Model::DescribeSpotInstanceRequestsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeSpotPriceHistory operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeSpotPriceHistoryPaginator(const Model::DescribeSpotPriceHistoryRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeStaleSecurityGroups operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeStaleSecurityGroupsPaginator(const Model::DescribeStaleSecurityGroupsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeStoreImageTasks operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeStoreImageTasksPaginator(const Model::DescribeStoreImageTasksRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeSubnets operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeSubnetsPaginator(const Model::DescribeSubnetsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeTags operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeTagsPaginator(const Model::DescribeTagsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeTrafficMirrorFilters operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeTrafficMirrorFiltersPaginator(const Model::DescribeTrafficMirrorFiltersRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeTrafficMirrorSessions operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeTrafficMirrorSessionsPaginator(const Model::DescribeTrafficMirrorSessionsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeTrafficMirrorTargets operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeTrafficMirrorTargetsPaginator(const Model::DescribeTrafficMirrorTargetsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeTransitGatewayAttachments operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeTransitGatewayAttachmentsPaginator(const Model::DescribeTransitGatewayAttachmentsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeTransitGatewayConnectPeers operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeTransitGatewayConnectPeersPaginator(const Model::DescribeTransitGatewayConnectPeersRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeTransitGatewayConnects operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeTransitGatewayConnectsPaginator(const Model::DescribeTransitGatewayConnectsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeTransitGatewayMulticastDomains operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeTransitGatewayMulticastDomainsPaginator(const Model::DescribeTransitGatewayMulticastDomainsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeTransitGatewayPeeringAttachments operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeTransitGatewayPeeringAttachmentsPaginator(const Model::DescribeTransitGatewayPeeringAttachmentsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeTransitGatewayPolicyTables operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeTransitGatewayPolicyTablesPaginator(const Model::DescribeTransitGatewayPolicyTablesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeTransitGatewayRouteTableAnnouncements operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeTransitGatewayRouteTableAnnouncementsPaginator(const Model::DescribeTransitGatewayRouteTableAnnouncementsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeTransitGatewayRouteTables operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeTransitGatewayRouteTablesPaginator(const Model::DescribeTransitGatewayRouteTablesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeTransitGateways operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeTransitGatewaysPaginator(const Model::DescribeTransitGatewaysRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeTransitGatewayVpcAttachments operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeTransitGatewayVpcAttachmentsPaginator(const Model::DescribeTransitGatewayVpcAttachmentsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeTrunkInterfaceAssociations operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeTrunkInterfaceAssociationsPaginator(const Model::DescribeTrunkInterfaceAssociationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeVerifiedAccessEndpoints operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeVerifiedAccessEndpointsPaginator(const Model::DescribeVerifiedAccessEndpointsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeVerifiedAccessGroups operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeVerifiedAccessGroupsPaginator(const Model::DescribeVerifiedAccessGroupsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeVerifiedAccessInstanceLoggingConfigurations operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeVerifiedAccessInstanceLoggingConfigurationsPaginator( + const Model::DescribeVerifiedAccessInstanceLoggingConfigurationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeVerifiedAccessInstances operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeVerifiedAccessInstancesPaginator(const Model::DescribeVerifiedAccessInstancesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeVerifiedAccessTrustProviders operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeVerifiedAccessTrustProvidersPaginator(const Model::DescribeVerifiedAccessTrustProvidersRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeVolumes operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeVolumesPaginator(const Model::DescribeVolumesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeVolumesModifications operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeVolumesModificationsPaginator(const Model::DescribeVolumesModificationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeVolumeStatus operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeVolumeStatusPaginator(const Model::DescribeVolumeStatusRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeVpcClassicLinkDnsSupport operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeVpcClassicLinkDnsSupportPaginator(const Model::DescribeVpcClassicLinkDnsSupportRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeVpcEndpointConnectionNotifications operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeVpcEndpointConnectionNotificationsPaginator(const Model::DescribeVpcEndpointConnectionNotificationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeVpcEndpointConnections operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeVpcEndpointConnectionsPaginator(const Model::DescribeVpcEndpointConnectionsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeVpcEndpoints operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeVpcEndpointsPaginator(const Model::DescribeVpcEndpointsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeVpcEndpointServiceConfigurations operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeVpcEndpointServiceConfigurationsPaginator(const Model::DescribeVpcEndpointServiceConfigurationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeVpcEndpointServicePermissions operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeVpcEndpointServicePermissionsPaginator(const Model::DescribeVpcEndpointServicePermissionsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeVpcPeeringConnections operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeVpcPeeringConnectionsPaginator(const Model::DescribeVpcPeeringConnectionsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeVpcs operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeVpcsPaginator(const Model::DescribeVpcsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for DescribeVpnConcentrators operation + */ + Aws::Utils::Pagination::PagePaginator + DescribeVpnConcentratorsPaginator(const Model::DescribeVpnConcentratorsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetAssociatedIpv6PoolCidrs operation + */ + Aws::Utils::Pagination::PagePaginator + GetAssociatedIpv6PoolCidrsPaginator(const Model::GetAssociatedIpv6PoolCidrsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetAwsNetworkPerformanceData operation + */ + Aws::Utils::Pagination::PagePaginator + GetAwsNetworkPerformanceDataPaginator(const Model::GetAwsNetworkPerformanceDataRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetCapacityManagerMetricData operation + */ + Aws::Utils::Pagination::PagePaginator + GetCapacityManagerMetricDataPaginator(const Model::GetCapacityManagerMetricDataRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetCapacityManagerMetricDimensions operation + */ + Aws::Utils::Pagination::PagePaginator + GetCapacityManagerMetricDimensionsPaginator(const Model::GetCapacityManagerMetricDimensionsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetGroupsForCapacityReservation operation + */ + Aws::Utils::Pagination::PagePaginator + GetGroupsForCapacityReservationPaginator(const Model::GetGroupsForCapacityReservationRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetInstanceTypesFromInstanceRequirements operation + */ + Aws::Utils::Pagination::PagePaginator + GetInstanceTypesFromInstanceRequirementsPaginator(const Model::GetInstanceTypesFromInstanceRequirementsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetIpamAddressHistory operation + */ + Aws::Utils::Pagination::PagePaginator + GetIpamAddressHistoryPaginator(const Model::GetIpamAddressHistoryRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetIpamDiscoveredAccounts operation + */ + Aws::Utils::Pagination::PagePaginator + GetIpamDiscoveredAccountsPaginator(const Model::GetIpamDiscoveredAccountsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetIpamDiscoveredResourceCidrs operation + */ + Aws::Utils::Pagination::PagePaginator + GetIpamDiscoveredResourceCidrsPaginator(const Model::GetIpamDiscoveredResourceCidrsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetIpamPoolAllocations operation + */ + Aws::Utils::Pagination::PagePaginator + GetIpamPoolAllocationsPaginator(const Model::GetIpamPoolAllocationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetIpamPoolCidrs operation + */ + Aws::Utils::Pagination::PagePaginator + GetIpamPoolCidrsPaginator(const Model::GetIpamPoolCidrsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetIpamPrefixListResolverRules operation + */ + Aws::Utils::Pagination::PagePaginator + GetIpamPrefixListResolverRulesPaginator(const Model::GetIpamPrefixListResolverRulesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetIpamPrefixListResolverVersionEntries operation + */ + Aws::Utils::Pagination::PagePaginator + GetIpamPrefixListResolverVersionEntriesPaginator(const Model::GetIpamPrefixListResolverVersionEntriesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetIpamPrefixListResolverVersions operation + */ + Aws::Utils::Pagination::PagePaginator + GetIpamPrefixListResolverVersionsPaginator(const Model::GetIpamPrefixListResolverVersionsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetIpamResourceCidrs operation + */ + Aws::Utils::Pagination::PagePaginator + GetIpamResourceCidrsPaginator(const Model::GetIpamResourceCidrsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetManagedPrefixListAssociations operation + */ + Aws::Utils::Pagination::PagePaginator + GetManagedPrefixListAssociationsPaginator(const Model::GetManagedPrefixListAssociationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetManagedPrefixListEntries operation + */ + Aws::Utils::Pagination::PagePaginator + GetManagedPrefixListEntriesPaginator(const Model::GetManagedPrefixListEntriesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetNetworkInsightsAccessScopeAnalysisFindings operation + */ + Aws::Utils::Pagination::PagePaginator + GetNetworkInsightsAccessScopeAnalysisFindingsPaginator(const Model::GetNetworkInsightsAccessScopeAnalysisFindingsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetSecurityGroupsForVpc operation + */ + Aws::Utils::Pagination::PagePaginator + GetSecurityGroupsForVpcPaginator(const Model::GetSecurityGroupsForVpcRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetSpotPlacementScores operation + */ + Aws::Utils::Pagination::PagePaginator + GetSpotPlacementScoresPaginator(const Model::GetSpotPlacementScoresRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetTransitGatewayAttachmentPropagations operation + */ + Aws::Utils::Pagination::PagePaginator + GetTransitGatewayAttachmentPropagationsPaginator(const Model::GetTransitGatewayAttachmentPropagationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetTransitGatewayMulticastDomainAssociations operation + */ + Aws::Utils::Pagination::PagePaginator + GetTransitGatewayMulticastDomainAssociationsPaginator(const Model::GetTransitGatewayMulticastDomainAssociationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetTransitGatewayPolicyTableAssociations operation + */ + Aws::Utils::Pagination::PagePaginator + GetTransitGatewayPolicyTableAssociationsPaginator(const Model::GetTransitGatewayPolicyTableAssociationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetTransitGatewayPrefixListReferences operation + */ + Aws::Utils::Pagination::PagePaginator + GetTransitGatewayPrefixListReferencesPaginator(const Model::GetTransitGatewayPrefixListReferencesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetTransitGatewayRouteTableAssociations operation + */ + Aws::Utils::Pagination::PagePaginator + GetTransitGatewayRouteTableAssociationsPaginator(const Model::GetTransitGatewayRouteTableAssociationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetTransitGatewayRouteTablePropagations operation + */ + Aws::Utils::Pagination::PagePaginator + GetTransitGatewayRouteTablePropagationsPaginator(const Model::GetTransitGatewayRouteTablePropagationsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for GetVpnConnectionDeviceTypes operation + */ + Aws::Utils::Pagination::PagePaginator + GetVpnConnectionDeviceTypesPaginator(const Model::GetVpnConnectionDeviceTypesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for ListImagesInRecycleBin operation + */ + Aws::Utils::Pagination::PagePaginator + ListImagesInRecycleBinPaginator(const Model::ListImagesInRecycleBinRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for ListSnapshotsInRecycleBin operation + */ + Aws::Utils::Pagination::PagePaginator + ListSnapshotsInRecycleBinPaginator(const Model::ListSnapshotsInRecycleBinRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for SearchLocalGatewayRoutes operation + */ + Aws::Utils::Pagination::PagePaginator + SearchLocalGatewayRoutesPaginator(const Model::SearchLocalGatewayRoutesRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for SearchTransitGatewayMulticastGroups operation + */ + Aws::Utils::Pagination::PagePaginator + SearchTransitGatewayMulticastGroupsPaginator(const Model::SearchTransitGatewayMulticastGroupsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } +}; +} // namespace EC2 +} // namespace Aws diff --git a/generated/src/aws-cpp-sdk-ec2/include/aws/ec2/model/pagination/DescribeSpotPriceHistoryPaginationTraits.h b/generated/src/aws-cpp-sdk-ec2/include/aws/ec2/model/DescribeSpotPriceHistoryPaginationTraits.h similarity index 79% rename from generated/src/aws-cpp-sdk-ec2/include/aws/ec2/model/pagination/DescribeSpotPriceHistoryPaginationTraits.h rename to generated/src/aws-cpp-sdk-ec2/include/aws/ec2/model/DescribeSpotPriceHistoryPaginationTraits.h index 871357593c24..b46693ff9250 100644 --- a/generated/src/aws-cpp-sdk-ec2/include/aws/ec2/model/pagination/DescribeSpotPriceHistoryPaginationTraits.h +++ b/generated/src/aws-cpp-sdk-ec2/include/aws/ec2/model/DescribeSpotPriceHistoryPaginationTraits.h @@ -4,13 +4,14 @@ */ #pragma once -#include +#include #include #include #include namespace Aws { namespace EC2 { +class EC2Client; namespace Pagination { struct DescribeSpotPriceHistoryPaginationTraits { @@ -19,7 +20,10 @@ struct DescribeSpotPriceHistoryPaginationTraits { using OutcomeType = Model::DescribeSpotPriceHistoryOutcome; using ClientType = EC2Client; - static OutcomeType Invoke(ClientType& client, const RequestType& request) { return client.DescribeSpotPriceHistory(request); } + template + static OutcomeType Invoke(Client& client, const RequestType& request) { + return client.DescribeSpotPriceHistory(request); + } static bool HasMoreResults(const ResultType& result) { return !result.GetNextToken().empty(); } diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/S3Client.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/S3Client.h index 7e036d82a8c5..65454163aa02 100644 --- a/generated/src/aws-cpp-sdk-s3/include/aws/s3/S3Client.h +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/S3Client.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -36,7 +37,9 @@ static const unsigned MAX_EXPIRATION_SECONDS = 7 * 24 * 60 * 60; /** *

*/ -class AWS_S3_API S3Client : public Aws::Client::AWSXMLClient, public Aws::Client::ClientWithAsyncTemplateMethods { +class AWS_S3_API S3Client : public Aws::Client::AWSXMLClient, + public Aws::Client::ClientWithAsyncTemplateMethods, + public S3PaginationBase { public: typedef Aws::Client::AWSXMLClient BASECLASS; static const char* GetServiceName(); diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/S3ClientPagination.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/S3ClientPagination.h index 9afd5a3e9908..c2853b35f652 100644 --- a/generated/src/aws-cpp-sdk-s3/include/aws/s3/S3ClientPagination.h +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/S3ClientPagination.h @@ -6,10 +6,10 @@ #pragma once #include #include -#include -#include -#include -#include +#include +#include +#include +#include namespace Aws { namespace S3 { diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/S3PaginationBase.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/S3PaginationBase.h new file mode 100644 index 000000000000..d7156cc705e7 --- /dev/null +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/S3PaginationBase.h @@ -0,0 +1,62 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include + +namespace Aws { +namespace S3 { + +class S3Client; + +template +class S3PaginationBase { + public: + /** + * Create a paginator for ListBuckets operation + */ + Aws::Utils::Pagination::PagePaginator + ListBucketsPaginator(const Model::ListBucketsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for ListDirectoryBuckets operation + */ + Aws::Utils::Pagination::PagePaginator + ListDirectoryBucketsPaginator(const Model::ListDirectoryBucketsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for ListObjectsV2 operation + */ + Aws::Utils::Pagination::PagePaginator + ListObjectsV2Paginator(const Model::ListObjectsV2Request& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } + + /** + * Create a paginator for ListParts operation + */ + Aws::Utils::Pagination::PagePaginator ListPartsPaginator( + const Model::ListPartsRequest& request) { + return Aws::Utils::Pagination::PagePaginator{ + std::shared_ptr(static_cast(this), [](DerivedClient*) {}), request}; + } +}; +} // namespace S3 +} // namespace Aws diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListBucketsPaginationTraits.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/ListBucketsPaginationTraits.h similarity index 79% rename from generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListBucketsPaginationTraits.h rename to generated/src/aws-cpp-sdk-s3/include/aws/s3/model/ListBucketsPaginationTraits.h index a3ab75a45a20..272aabe4e831 100644 --- a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListBucketsPaginationTraits.h +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/ListBucketsPaginationTraits.h @@ -4,13 +4,14 @@ */ #pragma once -#include +#include #include #include #include namespace Aws { namespace S3 { +class S3Client; namespace Pagination { struct ListBucketsPaginationTraits { @@ -19,7 +20,10 @@ struct ListBucketsPaginationTraits { using OutcomeType = Model::ListBucketsOutcome; using ClientType = S3Client; - static OutcomeType Invoke(ClientType& client, const RequestType& request) { return client.ListBuckets(request); } + template + static OutcomeType Invoke(Client& client, const RequestType& request) { + return client.ListBuckets(request); + } static bool HasMoreResults(const ResultType& result) { return !result.GetContinuationToken().empty(); } diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListDirectoryBucketsPaginationTraits.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/ListDirectoryBucketsPaginationTraits.h similarity index 79% rename from generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListDirectoryBucketsPaginationTraits.h rename to generated/src/aws-cpp-sdk-s3/include/aws/s3/model/ListDirectoryBucketsPaginationTraits.h index f7f6de8b6fcc..558e26aa71c8 100644 --- a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListDirectoryBucketsPaginationTraits.h +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/ListDirectoryBucketsPaginationTraits.h @@ -4,13 +4,14 @@ */ #pragma once -#include +#include #include #include #include namespace Aws { namespace S3 { +class S3Client; namespace Pagination { struct ListDirectoryBucketsPaginationTraits { @@ -19,7 +20,10 @@ struct ListDirectoryBucketsPaginationTraits { using OutcomeType = Model::ListDirectoryBucketsOutcome; using ClientType = S3Client; - static OutcomeType Invoke(ClientType& client, const RequestType& request) { return client.ListDirectoryBuckets(request); } + template + static OutcomeType Invoke(Client& client, const RequestType& request) { + return client.ListDirectoryBuckets(request); + } static bool HasMoreResults(const ResultType& result) { return !result.GetContinuationToken().empty(); } diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListObjectsV2PaginationTraits.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/ListObjectsV2PaginationTraits.h similarity index 79% rename from generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListObjectsV2PaginationTraits.h rename to generated/src/aws-cpp-sdk-s3/include/aws/s3/model/ListObjectsV2PaginationTraits.h index 718d63337787..a8968e1a0d03 100644 --- a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListObjectsV2PaginationTraits.h +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/ListObjectsV2PaginationTraits.h @@ -4,13 +4,14 @@ */ #pragma once -#include +#include #include #include #include namespace Aws { namespace S3 { +class S3Client; namespace Pagination { struct ListObjectsV2PaginationTraits { @@ -19,7 +20,10 @@ struct ListObjectsV2PaginationTraits { using OutcomeType = Model::ListObjectsV2Outcome; using ClientType = S3Client; - static OutcomeType Invoke(ClientType& client, const RequestType& request) { return client.ListObjectsV2(request); } + template + static OutcomeType Invoke(Client& client, const RequestType& request) { + return client.ListObjectsV2(request); + } static bool HasMoreResults(const ResultType& result) { return !result.GetNextContinuationToken().empty(); } diff --git a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/ListPartsPaginationTraits.h similarity index 79% rename from generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h rename to generated/src/aws-cpp-sdk-s3/include/aws/s3/model/ListPartsPaginationTraits.h index dc6a20a510d9..78ce1d6b4b1f 100644 --- a/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/pagination/ListPartsPaginationTraits.h +++ b/generated/src/aws-cpp-sdk-s3/include/aws/s3/model/ListPartsPaginationTraits.h @@ -4,13 +4,14 @@ */ #pragma once -#include +#include #include #include #include namespace Aws { namespace S3 { +class S3Client; namespace Pagination { struct ListPartsPaginationTraits { @@ -19,7 +20,10 @@ struct ListPartsPaginationTraits { using OutcomeType = Model::ListPartsOutcome; using ClientType = S3Client; - static OutcomeType Invoke(ClientType& client, const RequestType& request) { return client.ListParts(request); } + template + static OutcomeType Invoke(Client& client, const RequestType& request) { + return client.ListParts(request); + } static bool HasMoreResults(const ResultType& result) { return result.GetNextPartNumberMarker() != 0; } diff --git a/generated/tests/dynamodb-gen-tests/DynamoDBPaginationCompilationTests.cpp b/generated/tests/dynamodb-gen-tests/DynamoDBPaginationCompilationTests.cpp index c4e9ee0bb112..2cf383ab5857 100644 --- a/generated/tests/dynamodb-gen-tests/DynamoDBPaginationCompilationTests.cpp +++ b/generated/tests/dynamodb-gen-tests/DynamoDBPaginationCompilationTests.cpp @@ -7,12 +7,13 @@ // This test ensures all generated pagination headers compile successfully #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include diff --git a/generated/tests/ec2-gen-tests/EC2PaginationCompilationTests.cpp b/generated/tests/ec2-gen-tests/EC2PaginationCompilationTests.cpp index 9ec13d3291ac..9a477cb17b1a 100644 --- a/generated/tests/ec2-gen-tests/EC2PaginationCompilationTests.cpp +++ b/generated/tests/ec2-gen-tests/EC2PaginationCompilationTests.cpp @@ -7,169 +7,170 @@ // This test ensures all generated pagination headers compile successfully #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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/S3PaginationCompilationTests.cpp b/generated/tests/s3-gen-tests/S3PaginationCompilationTests.cpp index 9ea1602aebcb..d35f2a6692e6 100644 --- a/generated/tests/s3-gen-tests/S3PaginationCompilationTests.cpp +++ b/generated/tests/s3-gen-tests/S3PaginationCompilationTests.cpp @@ -7,10 +7,11 @@ // This test ensures all generated pagination headers compile successfully #include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include diff --git a/tests/aws-cpp-sdk-dynamodb-integration-tests/ScanPaginationIntegrationTest.cpp b/tests/aws-cpp-sdk-dynamodb-integration-tests/ScanPaginationIntegrationTest.cpp index a7dc27adcf87..e5c5bd86dcab 100644 --- a/tests/aws-cpp-sdk-dynamodb-integration-tests/ScanPaginationIntegrationTest.cpp +++ b/tests/aws-cpp-sdk-dynamodb-integration-tests/ScanPaginationIntegrationTest.cpp @@ -3,6 +3,8 @@ * SPDX-License-Identifier: Apache-2.0. */ +// TODO: Uncomment and test to identify which integration test is the bottleneck +/* #include #include #include @@ -15,7 +17,7 @@ #include #include #include -#include +#include #include #include @@ -208,4 +210,5 @@ TEST_F(ScanPaginationTest, TestManualPaginationWithExclusiveStartKey) { } while (true); EXPECT_EQ(ITEM_COUNT, allItems.size()); -} \ No newline at end of file +} +*/ \ No newline at end of file diff --git a/tests/aws-cpp-sdk-ec2-integration-tests/EC2PaginationIntegrationTest.cpp b/tests/aws-cpp-sdk-ec2-integration-tests/EC2PaginationIntegrationTest.cpp index ed129d874a9e..142ccde5a1d2 100644 --- a/tests/aws-cpp-sdk-ec2-integration-tests/EC2PaginationIntegrationTest.cpp +++ b/tests/aws-cpp-sdk-ec2-integration-tests/EC2PaginationIntegrationTest.cpp @@ -3,12 +3,16 @@ * SPDX-License-Identifier: Apache-2.0. */ +// TODO: Update these tests to use the new paginator API directly: +// For example: for (const auto& outcome : ec2Client->DescribeSpotPriceHistoryPaginator(request)) { ... } +// instead of manual pagination with traits + #include #include #include #include #include -#include +#include #include #include diff --git a/tests/aws-cpp-sdk-s3-integration-tests/ListObjectsV2PaginationIntegrationTest.cpp b/tests/aws-cpp-sdk-s3-integration-tests/ListObjectsV2PaginationIntegrationTest.cpp index 1e2bca8bf450..da829edc337f 100644 --- a/tests/aws-cpp-sdk-s3-integration-tests/ListObjectsV2PaginationIntegrationTest.cpp +++ b/tests/aws-cpp-sdk-s3-integration-tests/ListObjectsV2PaginationIntegrationTest.cpp @@ -3,6 +3,8 @@ * SPDX-License-Identifier: Apache-2.0. */ +// TODO: Uncomment and test to identify which integration test is the bottleneck +/* #include #include #include @@ -15,7 +17,7 @@ #include #include #include -#include +#include #include #include @@ -259,3 +261,4 @@ TEST_F(ListObjectsV2PaginationTest, TestManualPaginationLoop) { EXPECT_EQ(OBJECT_COUNT, allKeys.size()); } +*/ \ No newline at end of file diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/json/JsonServiceClientHeader.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/json/JsonServiceClientHeader.vm index afc2578fc11e..be9467bd20e7 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/json/JsonServiceClientHeader.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/json/JsonServiceClientHeader.vm @@ -11,6 +11,7 @@ \#include \#include \#include +\#include namespace ${rootNamespace} { @@ -25,7 +26,7 @@ namespace ${serviceNamespace} #if($serviceModel.enableVirtualOperations) #set($finalClass = "") #end - class ${CppViewHelper.computeExportValue($metadata.classNamePrefix)} ${className}${finalClass} : public Aws::Client::AWSJsonClient, public Aws::Client::ClientWithAsyncTemplateMethods<${className}> + class ${CppViewHelper.computeExportValue($metadata.classNamePrefix)} ${className}${finalClass} : public Aws::Client::AWSJsonClient, public Aws::Client::ClientWithAsyncTemplateMethods<${className}>, public ${metadata.classNamePrefix}PaginationBase<${className}> { public: typedef Aws::Client::AWSJsonClient BASECLASS; diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/S3ClientHeader.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/S3ClientHeader.vm index fe7385b9efa5..4d2b11c58ad7 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/S3ClientHeader.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/s3/S3ClientHeader.vm @@ -22,6 +22,7 @@ \#include \#include \#include +\#include #if($serviceNamespace == "S3Crt") \#include \#include @@ -94,7 +95,7 @@ namespace ${rootNamespace} #if($serviceModel.enableVirtualOperations) #set($finalClass = "") #end - class ${CppViewHelper.computeExportValue($metadata.classNamePrefix)} ${className}${finalClass} : public Aws::Client::AWSXMLClient, public Aws::Client::ClientWithAsyncTemplateMethods<${className}> + class ${CppViewHelper.computeExportValue($metadata.classNamePrefix)} ${className}${finalClass} : public Aws::Client::AWSXMLClient, public Aws::Client::ClientWithAsyncTemplateMethods<${className}>, public ${metadata.classNamePrefix}PaginationBase<${className}> { public: typedef Aws::Client::AWSXMLClient BASECLASS; diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm index da58148a0909..37932a673031 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/smithy/SmithyClientHeader.vm @@ -17,6 +17,7 @@ \#include \#include \#include +\#include \#include #if($serviceModel.hasBearerAuth()) \#include @@ -56,7 +57,8 @@ namespace ${serviceNamespace} ${metadata.classNamePrefix}EndpointProviderBase, smithy::client::$serializer, smithy::client::$serializerOutcome, - Aws::Client::${metadata.classNamePrefix}ErrorMarshaller> + Aws::Client::${metadata.classNamePrefix}ErrorMarshaller>, + public ${metadata.classNamePrefix}PaginationBase<${className}> { public: static const char* GetServiceName(); diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlServiceClientHeader.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlServiceClientHeader.vm index 9112307c5039..e63b11a64561 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlServiceClientHeader.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlServiceClientHeader.vm @@ -12,6 +12,7 @@ \#include \#include \#include +\#include namespace ${rootNamespace} { @@ -26,7 +27,7 @@ namespace ${serviceNamespace} #if($serviceModel.enableVirtualOperations) #set($finalClass = "") #end - class ${CppViewHelper.computeExportValue($metadata.classNamePrefix)} ${className}$finalClass : public Aws::Client::AWSXMLClient, public Aws::Client::ClientWithAsyncTemplateMethods<${className}> + class ${CppViewHelper.computeExportValue($metadata.classNamePrefix)} ${className}$finalClass : public Aws::Client::AWSXMLClient, public Aws::Client::ClientWithAsyncTemplateMethods<${className}>, public ${metadata.classNamePrefix}PaginationBase<${className}> { public: typedef Aws::Client::AWSXMLClient BASECLASS; diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationBaseGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationBaseGenerator.java new file mode 100644 index 000000000000..833e3f1b559c --- /dev/null +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationBaseGenerator.java @@ -0,0 +1,96 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +package com.amazonaws.util.awsclientsmithygenerator.generators.templates; + +import com.amazonaws.util.awsclientsmithygenerator.generators.CppWriter; +import com.amazonaws.util.awsclientsmithygenerator.generators.OperationData; +import com.amazonaws.util.awsclientsmithygenerator.generators.ServiceNameUtil; +import com.amazonaws.util.awsclientsmithygenerator.generators.ShapeUtil; +import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.model.traits.PaginatedTrait; +import java.util.List; +import java.util.Map; + +public class PaginationBaseGenerator { + private final ServiceShape service; + private final List> paginatedOps; + private final Map serviceMap; + + public PaginationBaseGenerator(ServiceShape service, List> paginatedOps, Map serviceMap) { + this.service = service; + this.paginatedOps = paginatedOps; + this.serviceMap = serviceMap; + } + + public void render(CppWriter writer) { + String serviceName = ServiceNameUtil.getServiceName(service); + String smithyServiceName = ServiceNameUtil.getSmithyServiceName(service, serviceMap); + String classPrefix = ServiceNameUtil.getServiceNameUpperCamel(service); + + renderHeader(writer); + renderIncludes(writer, serviceName, smithyServiceName); + renderBaseClass(writer, serviceName, smithyServiceName, classPrefix); + } + + private void renderHeader(CppWriter writer) { + writer.write("/**") + .write(" * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.") + .write(" * SPDX-License-Identifier: Apache-2.0.") + .write(" */") + .write("") + .write("#pragma once") + .write(""); + } + + private void renderIncludes(CppWriter writer, String serviceName, String smithyServiceName) { + writer.writeInclude("memory"); + + // Include paginator headers + for (OperationData data : paginatedOps) { + String opName = data.getOperation().getId().getName(); + writer.writeInclude("aws/" + smithyServiceName + "/model/" + opName + "PaginationTraits.h"); + } + + writer.writeInclude("aws/core/utils/pagination/Paginator.h"); + writer.write(""); + } + + private void renderBaseClass(CppWriter writer, String serviceName, String smithyServiceName, String classPrefix) { + writer.writeNamespaceOpen("Aws"); + writer.writeNamespaceOpen(serviceName); + writer.write(""); + + // Forward declare the client + writer.write("class " + classPrefix + "Client;"); + writer.write(""); + + // CRTP base class + writer.write("template"); + writer.openBlock("class " + classPrefix + "PaginationBase {\npublic:", "};", () -> { + // Generate paginator methods + for (OperationData data : paginatedOps) { + String opName = data.getOperation().getId().getName(); + String methodName = ShapeUtil.getOperationMethodName(opName, smithyServiceName); + + writer.write(""); + writer.write("/**") + .write(" * Create a paginator for " + opName + " operation") + .write(" */"); + + writer.write("Aws::Utils::Pagination::PagePaginator") + .write(opName + "Paginator(const Model::" + methodName + "Request& request)"); + + writer.openBlock("{", "}", () -> { + writer.write("return Aws::Utils::Pagination::PagePaginator{") + .write(" std::shared_ptr(static_cast(this), [](DerivedClient*){}), request};"); + }); + } + }); + + writer.writeNamespaceClose(serviceName); + writer.writeNamespaceClose("Aws"); + + } +} \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java index 15d66d2288dc..cd6d3400e7db 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationClientHeaderGenerator.java @@ -51,7 +51,7 @@ private void renderIncludes(CppWriter writer, String serviceName, String smithyS for (OperationData data : paginatedOps) { String opName = data.getOperation().getId().getName(); - writer.writeInclude("aws/" + smithyServiceName + "/model/pagination/" + opName + "PaginationTraits.h"); + writer.writeInclude("aws/" + smithyServiceName + "/model/" + opName + "PaginationTraits.h"); } writer.write(""); } diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java index 24546026b545..a61f8e8bd1bf 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java @@ -15,6 +15,7 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationTraitsGenerator; import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationClientHeaderGenerator; import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationCompilationTestGenerator; +import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationBaseGenerator; import java.util.List; import java.util.stream.Collectors; @@ -49,6 +50,12 @@ public void execute(PluginContext context) { writer -> new PaginationClientHeaderGenerator(featureParser.getService(), featureParser.getOperations(), featureParser.getServiceMap()).render(writer) ); + // Generate CRTP pagination mixin + featureParser.generateClientHeader( + serviceName + "PaginationBase.h", + writer -> new PaginationBaseGenerator(featureParser.getService(), featureParser.getOperations(), featureParser.getServiceMap()).render(writer) + ); + // Generate pagination traits headers PaginationTraitsGenerator traitsGenerator = new PaginationTraitsGenerator( featureParser.getContext(), diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java index faafa09db679..fbda6b736615 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCompilationTestGenerator.java @@ -71,6 +71,7 @@ public void render(CppWriter writer) { private void writeIncludes(CppWriter writer) { Set clientHeaders = new HashSet<>(); Set traitHeaders = new HashSet<>(); + Set mixinHeaders = new HashSet<>(); for (OperationData paginationData : allPaginatedOps) { ServiceShape service = paginationData.getService(); @@ -80,9 +81,12 @@ private void writeIncludes(CppWriter writer) { // Collect unique client headers clientHeaders.add("aws/" + smithyServiceName + "/" + serviceName + "ClientPagination.h"); + // Collect unique mixin headers + mixinHeaders.add("aws/" + smithyServiceName + "/" + serviceName + "PaginationBase.h"); + // Collect unique trait headers String operationName = paginationData.getOperation().getId().getName(); - traitHeaders.add("aws/" + smithyServiceName + "/model/pagination/" + operationName + "PaginationTraits.h"); + traitHeaders.add("aws/" + smithyServiceName + "/model/" + operationName + "PaginationTraits.h"); } // Write unique client headers @@ -90,6 +94,11 @@ private void writeIncludes(CppWriter writer) { writer.writeInclude(header); } + // Write unique mixin headers + for (String header : mixinHeaders) { + writer.writeInclude(header); + } + // Write unique trait headers for (String header : traitHeaders) { writer.writeInclude(header); diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java index 915488e20110..cce819756f5c 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationTraitsGenerator.java @@ -36,7 +36,7 @@ public void write() { String serviceName = ServiceNameUtil.getServiceName(service); for (OperationData data : paginatedOps) { - String fileName = "include/aws/" + smithyServiceName + "/model/pagination/" + data.getOperation().getId().getName() + "PaginationTraits.h"; + String fileName = "include/aws/" + smithyServiceName + "/model/" + data.getOperation().getId().getName() + "PaginationTraits.h"; writerDelegator.useFileWriter(fileName, writer -> { generateTraitsHeader(writer, data, serviceName); @@ -64,30 +64,33 @@ private void generateTraitsHeader(CppWriter writer, OperationData { // Use detected suffix to match C2J renameShape logic - String methodName = ShapeUtil.getOperationMethodName(opName, smithyServiceName); writer.write(" using RequestType = Model::$LRequest;", methodName) .write(" using ResultType = Model::$L$L;", methodName, resultSuffix) .write(" using OutcomeType = Model::$LOutcome;", methodName) .write(" using ClientType = $LClient;", capitalizedServiceName) .write(""); - // Invoke method - writer.openBlock(" static OutcomeType Invoke(ClientType& client, const RequestType& request)\n {", " }", () -> { + // Invoke method - template to defer instantiation + writer.write(" template") + .openBlock(" static OutcomeType Invoke(Client& client, const RequestType& request)\n {", " }", () -> { writer.write(" return client.$L(request);", methodName); }); diff --git a/tools/code-generation/smithy/codegen/cpp-pagination/smithy-build.json b/tools/code-generation/smithy/codegen/cpp-pagination/smithy-build.json index 1008552afa3d..11f7416fb6a9 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination/smithy-build.json +++ b/tools/code-generation/smithy/codegen/cpp-pagination/smithy-build.json @@ -1,96 +1,6 @@ { "version": "1.0", "projections": { - "accessanalyzer.2019-11-01": { - "imports": [ - "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/accessanalyzer.json" - ], - "plugins": { - "cpp-codegen-pagination-plugin": { - "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" - } - } - }, - "elasticache.2015-02-02": { - "imports": [ - "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/elasticache.json" - ], - "plugins": { - "cpp-codegen-pagination-plugin": { - "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" - } - } - }, - "bedrock-agent-runtime.2023-07-26": { - "imports": [ - "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/bedrock-agent-runtime.json" - ], - "plugins": { - "cpp-codegen-pagination-plugin": { - "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" - } - } - }, - "amp.2020-08-01": { - "imports": [ - "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/amp.json" - ], - "plugins": { - "cpp-codegen-pagination-plugin": { - "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" - } - } - }, - "chatbot.2017-10-11": { - "imports": [ - "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/chatbot.json" - ], - "plugins": { - "cpp-codegen-pagination-plugin": { - "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" - } - } - }, - "lex-models-v2.2020-08-07": { - "imports": [ - "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/lex-models-v2.json" - ], - "plugins": { - "cpp-codegen-pagination-plugin": { - "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" - } - } - }, - "transfer.2018-11-05": { - "imports": [ - "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/transfer.json" - ], - "plugins": { - "cpp-codegen-pagination-plugin": { - "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" - } - } - }, - "ecr.2015-09-21": { - "imports": [ - "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/ecr.json" - ], - "plugins": { - "cpp-codegen-pagination-plugin": { - "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" - } - } - }, - "migration-hub.2017-05-31": { - "imports": [ - "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/migration-hub.json" - ], - "plugins": { - "cpp-codegen-pagination-plugin": { - "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" - } - } - }, "ec2.2016-11-15": { "imports": [ "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/ec2.json" @@ -101,16 +11,6 @@ } } }, - "b2bi.2022-06-23": { - "imports": [ - "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/b2bi.json" - ], - "plugins": { - "cpp-codegen-pagination-plugin": { - "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" - } - } - }, "s3.2006-03-01": { "imports": [ "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/s3.json" @@ -121,56 +21,6 @@ } } }, - "appintegrations.2020-07-29": { - "imports": [ - "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/appintegrations.json" - ], - "plugins": { - "cpp-codegen-pagination-plugin": { - "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" - } - } - }, - "amplify.2017-07-25": { - "imports": [ - "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/amplify.json" - ], - "plugins": { - "cpp-codegen-pagination-plugin": { - "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" - } - } - }, - "codestar-notifications.2019-10-15": { - "imports": [ - "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/codestar-notifications.json" - ], - "plugins": { - "cpp-codegen-pagination-plugin": { - "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" - } - } - }, - "cloudfront.2020-05-31": { - "imports": [ - "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/cloudfront.json" - ], - "plugins": { - "cpp-codegen-pagination-plugin": { - "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" - } - } - }, - "medialive.2017-10-14": { - "imports": [ - "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/medialive.json" - ], - "plugins": { - "cpp-codegen-pagination-plugin": { - "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" - } - } - }, "dynamodb.2012-08-10": { "imports": [ "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/dynamodb.json" From 3dd6a5c7c4afe1820bbb1d3192e7e208958763d2 Mon Sep 17 00:00:00 2001 From: kai lin Date: Tue, 27 Jan 2026 20:51:45 -0500 Subject: [PATCH 39/46] updated script to not traverse thru the entire dir --- tools/scripts/codegen/pagination_gen.py | 9 ++++++++- tools/scripts/codegen/smoke_tests_gen.py | 11 +++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/tools/scripts/codegen/pagination_gen.py b/tools/scripts/codegen/pagination_gen.py index 5a70e7319714..7fc6498674d7 100644 --- a/tools/scripts/codegen/pagination_gen.py +++ b/tools/scripts/codegen/pagination_gen.py @@ -72,7 +72,14 @@ def _generate_pagination(self, smithy_services: List[str], smithy_c2j_data: str) return False def _copy_cpp_codegen_contents(self, top_level_dir: str, plugin_name: str, target_dir: str): - for root, dirs, files in os.walk(top_level_dir): + # Walk only cpp-pagination subdirectory to avoid .git and gradle cache + cpp_pagination_dir = os.path.join(top_level_dir, "cpp-pagination") + if not os.path.exists(cpp_pagination_dir): + if self.debug: + print(f"No cpp-pagination directory found at '{cpp_pagination_dir}'") + return + + for root, dirs, files in os.walk(cpp_pagination_dir): if plugin_name in dirs: source_dir = os.path.join(root, plugin_name) diff --git a/tools/scripts/codegen/smoke_tests_gen.py b/tools/scripts/codegen/smoke_tests_gen.py index 8aea19b5c1eb..99f6f636091e 100644 --- a/tools/scripts/codegen/smoke_tests_gen.py +++ b/tools/scripts/codegen/smoke_tests_gen.py @@ -103,8 +103,15 @@ def _copy_cpp_codegen_contents(self, top_level_dir: str, plugin_name: str, targe if self.debug: print(f"_copy_cpp_codegen_contents: {target_dir}") - # Walk through the top-level directory and find all "cpp-codegen-smoke-tests-plugin" directories - for root, dirs, files in os.walk(top_level_dir): + # Walk only cpp-smoke-tests subdirectory to avoid .git and gradle cache + cpp_smoke_tests_dir = os.path.join(top_level_dir, "cpp-smoke-tests") + if not os.path.exists(cpp_smoke_tests_dir): + if self.debug: + print(f"No cpp-smoke-tests directory found at '{cpp_smoke_tests_dir}'") + return + + # Walk through the cpp-smoke-tests directory and find all plugin directories + for root, dirs, files in os.walk(cpp_smoke_tests_dir): if plugin_name in dirs: source_dir = os.path.join(root, plugin_name) # recursively copy all contents from the source to the target folder From 7cedec3297214290ecaa842eab42b406e13bf1b7 Mon Sep 17 00:00:00 2001 From: kai lin Date: Tue, 27 Jan 2026 21:19:47 -0500 Subject: [PATCH 40/46] updated script to not traverse thru the entire dir --- tools/scripts/codegen/smoke_tests_gen.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/scripts/codegen/smoke_tests_gen.py b/tools/scripts/codegen/smoke_tests_gen.py index 99f6f636091e..1b8364699f5f 100644 --- a/tools/scripts/codegen/smoke_tests_gen.py +++ b/tools/scripts/codegen/smoke_tests_gen.py @@ -67,8 +67,8 @@ def generate(self, clients_to_build: set): def _generate_smoke_tests(self, smithy_services: List[str], smithy_c2j_data: str): smithy_codegen_command = [ "./gradlew", - "clean", - "build", + ":cpp-smoke-tests:clean", + ":cpp-smoke-tests:build", "-PoutputDirectory=" + SMITHY_OUTPUT_DIR, "-PservicesFilter=" + ",".join(smithy_services), "-Pc2jMap=" + smithy_c2j_data From 2bd0fdb326a3eee62431ef175e8192cf36f908bf Mon Sep 17 00:00:00 2001 From: kai lin Date: Tue, 27 Jan 2026 23:16:05 -0500 Subject: [PATCH 41/46] updated script to not traverse thru the entire dir. and to generate pagination base even if there is no paginate trait --- .../templates/PaginationBaseGenerator.java | 40 +++++++++++-------- .../templates/PaginationCodegenPlugin.java | 31 +++++++------- tools/scripts/codegen/pagination_gen.py | 1 + tools/scripts/codegen/smoke_tests_gen.py | 1 + 4 files changed, 42 insertions(+), 31 deletions(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationBaseGenerator.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationBaseGenerator.java index 833e3f1b559c..ea40a4c5d442 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationBaseGenerator.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationBaseGenerator.java @@ -69,23 +69,29 @@ private void renderBaseClass(CppWriter writer, String serviceName, String smithy // CRTP base class writer.write("template"); writer.openBlock("class " + classPrefix + "PaginationBase {\npublic:", "};", () -> { - // Generate paginator methods - for (OperationData data : paginatedOps) { - String opName = data.getOperation().getId().getName(); - String methodName = ShapeUtil.getOperationMethodName(opName, smithyServiceName); - - writer.write(""); - writer.write("/**") - .write(" * Create a paginator for " + opName + " operation") - .write(" */"); - - writer.write("Aws::Utils::Pagination::PagePaginator") - .write(opName + "Paginator(const Model::" + methodName + "Request& request)"); - - writer.openBlock("{", "}", () -> { - writer.write("return Aws::Utils::Pagination::PagePaginator{") - .write(" std::shared_ptr(static_cast(this), [](DerivedClient*){}), request};"); - }); + if (paginatedOps.isEmpty()) { + // Empty base class for services without pagination + // Required because legacy C2J generator always includes PaginationBase inheritance in client headers + writer.write("virtual ~" + classPrefix + "PaginationBase() = default;"); + } else { + // Generate paginator methods + for (OperationData data : paginatedOps) { + String opName = data.getOperation().getId().getName(); + String methodName = ShapeUtil.getOperationMethodName(opName, smithyServiceName); + + writer.write(""); + writer.write("/**") + .write(" * Create a paginator for " + opName + " operation") + .write(" */"); + + writer.write("Aws::Utils::Pagination::PagePaginator") + .write(opName + "Paginator(const Model::" + methodName + "Request& request)"); + + writer.openBlock("{", "}", () -> { + writer.write("return Aws::Utils::Pagination::PagePaginator{") + .write(" std::shared_ptr(static_cast(this), [](DerivedClient*){}), request};"); + }); + } } }); diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java index a61f8e8bd1bf..8ee5e579f8f4 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java @@ -38,24 +38,25 @@ public void execute(PluginContext context) { .map(op -> new OperationData<>(op, op.expectTrait(PaginatedTrait.class), service)) .collect(Collectors.toList()); - if (!paginatedOps.isEmpty()) { - // Generate pagination files - FeatureParser> parser = new FeatureParser<>(context, service, paginatedOps, "Pagination"); - parser.run(featureParser -> { - String serviceName = ServiceNameUtil.getServiceNameUpperCamel(featureParser.getService()); - + // Always generate base class, even if empty + // Required because legacy C2J generator always includes PaginationBase inheritance in client headers + FeatureParser> parser = new FeatureParser<>(context, service, paginatedOps, "Pagination"); + parser.run(featureParser -> { + String serviceName = ServiceNameUtil.getServiceNameUpperCamel(featureParser.getService()); + + // Generate CRTP pagination mixin (always, even if empty) + featureParser.generateClientHeader( + serviceName + "PaginationBase.h", + writer -> new PaginationBaseGenerator(featureParser.getService(), featureParser.getOperations(), featureParser.getServiceMap()).render(writer) + ); + + if (!paginatedOps.isEmpty()) { // Generate client pagination header featureParser.generateClientHeader( serviceName + "ClientPagination.h", writer -> new PaginationClientHeaderGenerator(featureParser.getService(), featureParser.getOperations(), featureParser.getServiceMap()).render(writer) ); - // Generate CRTP pagination mixin - featureParser.generateClientHeader( - serviceName + "PaginationBase.h", - writer -> new PaginationBaseGenerator(featureParser.getService(), featureParser.getOperations(), featureParser.getServiceMap()).render(writer) - ); - // Generate pagination traits headers PaginationTraitsGenerator traitsGenerator = new PaginationTraitsGenerator( featureParser.getContext(), @@ -64,8 +65,10 @@ public void execute(PluginContext context) { featureParser.getSmithyServiceName() ); traitsGenerator.write(); - }); - + } + }); + + if (!paginatedOps.isEmpty()) { // Generate compilation test PaginationCompilationTestGenerator testGenerator = new PaginationCompilationTestGenerator(context, service, paginatedOps, parser.getServiceMap()); testGenerator.run(); diff --git a/tools/scripts/codegen/pagination_gen.py b/tools/scripts/codegen/pagination_gen.py index 7fc6498674d7..67f34153327f 100644 --- a/tools/scripts/codegen/pagination_gen.py +++ b/tools/scripts/codegen/pagination_gen.py @@ -74,6 +74,7 @@ def _generate_pagination(self, smithy_services: List[str], smithy_c2j_data: str) def _copy_cpp_codegen_contents(self, top_level_dir: str, plugin_name: str, target_dir: str): # Walk only cpp-pagination subdirectory to avoid .git and gradle cache cpp_pagination_dir = os.path.join(top_level_dir, "cpp-pagination") + # TODO: Verify if this check is still needed after Smithy generator always creates output if not os.path.exists(cpp_pagination_dir): if self.debug: print(f"No cpp-pagination directory found at '{cpp_pagination_dir}'") diff --git a/tools/scripts/codegen/smoke_tests_gen.py b/tools/scripts/codegen/smoke_tests_gen.py index 1b8364699f5f..290995a1f197 100644 --- a/tools/scripts/codegen/smoke_tests_gen.py +++ b/tools/scripts/codegen/smoke_tests_gen.py @@ -105,6 +105,7 @@ def _copy_cpp_codegen_contents(self, top_level_dir: str, plugin_name: str, targe # Walk only cpp-smoke-tests subdirectory to avoid .git and gradle cache cpp_smoke_tests_dir = os.path.join(top_level_dir, "cpp-smoke-tests") + # TODO: Verify if this check is still needed after Smithy generator always creates output if not os.path.exists(cpp_smoke_tests_dir): if self.debug: print(f"No cpp-smoke-tests directory found at '{cpp_smoke_tests_dir}'") From a92eb251e7025659081803357ba66468b9d349aa Mon Sep 17 00:00:00 2001 From: kai lin Date: Wed, 28 Jan 2026 01:05:17 -0500 Subject: [PATCH 42/46] some services only exist in c2j and not smithy, added temporary solution to generate them --- .../templates/PaginationCodegenPlugin.java | 60 +++++++++++++++++++ .../codegen/cpp-pagination/build.gradle.kts | 16 +++++ 2 files changed, 76 insertions(+) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java index 8ee5e579f8f4..36d259a91685 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java @@ -17,7 +17,12 @@ import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationCompilationTestGenerator; import com.amazonaws.util.awsclientsmithygenerator.generators.templates.PaginationBaseGenerator; import java.util.List; +import java.util.Map; +import java.util.HashMap; import java.util.stream.Collectors; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; public class PaginationCodegenPlugin implements SmithyBuildPlugin { @@ -30,6 +35,15 @@ public String getName() { public void execute(PluginContext context) { var model = context.getModel(); + // TODO: Remove this workaround - mock projections should use proper Smithy model generation + // instead of manually writing files in the plugin + // Check if this is a legacy service mock projection + String projectionName = context.getProjectionName(); + if (projectionName.endsWith(".mock")) { + generateLegacyServiceFile(context); + return; + } + for (ServiceShape service : model.getServiceShapes()) { // Find paginated operations using TopDownIndex, excluding deprecated operations List> paginatedOps = TopDownIndex.of(model).getContainedOperations(service).stream() @@ -75,4 +89,50 @@ public void execute(PluginContext context) { } } } + + private void generateLegacyServiceFile(PluginContext context) { + Map legacyServices = new HashMap<>(); + legacyServices.put("importexport", "ImportExport"); + legacyServices.put("sdb", "SimpleDB"); + + String projectionName = context.getProjectionName(); + String c2jName = projectionName.replace(".mock", ""); + String pascalName = legacyServices.get(c2jName); + + if (pascalName == null) { + return; + } + + try { + Path baseDir = context.getFileManifest().getBaseDir(); + Path includeDir = baseDir.resolve("include").resolve("aws").resolve(c2jName); + Files.createDirectories(includeDir); + + // Generate empty pagination base header + Path headerFile = includeDir.resolve(pascalName + "PaginationBase.h"); + String content = String.format( + "/**\n" + + " * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n" + + " * SPDX-License-Identifier: Apache-2.0.\n" + + " */\n\n" + + "#pragma once\n\n" + + "namespace Aws\n" + + "{\n" + + " namespace %s\n" + + " {\n" + + " template\n" + + " class %sPaginationBase\n" + + " {\n" + + " public:\n" + + " virtual ~%sPaginationBase() = default;\n" + + " };\n" + + " } // namespace %s\n" + + "} // namespace Aws\n", + pascalName, pascalName, pascalName, pascalName + ); + Files.writeString(headerFile, content); + } catch (Exception e) { + System.err.println("Failed to generate legacy service " + c2jName + ": " + e.getMessage()); + } + } } diff --git a/tools/code-generation/smithy/codegen/cpp-pagination/build.gradle.kts b/tools/code-generation/smithy/codegen/cpp-pagination/build.gradle.kts index e6fc1e2a6894..5a10c53e4afb 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination/build.gradle.kts +++ b/tools/code-generation/smithy/codegen/cpp-pagination/build.gradle.kts @@ -75,6 +75,22 @@ tasks.register("generate-smithy-build") { projectionsBuilder.withMember("$sdkId.${service.version.lowercase()}", projectionContents) } + // TODO: Remove this workaround - legacy services should have proper Smithy models + // instead of hardcoding service names in both Gradle and Java + // Add mock projections for legacy C2J-only services + val legacyServices = mapOf("importexport" to "ImportExport", "sdb" to "SimpleDB") + legacyServices.forEach { (c2jName, pascalName) -> + if (filteredServiceList.isEmpty() || c2jName in filteredServiceList) { + val mockProjectionContents = Node.objectNodeBuilder() + .withMember("plugins", Node.objectNode() + .withMember("cpp-codegen-pagination-plugin", Node.objectNodeBuilder() + .withMember("c2jMap", Node.from(c2jMapStr)) + .build())) + .build() + projectionsBuilder.withMember("$c2jName.mock", mockProjectionContents) + } + } + val outputDirectoryArg = project.findProperty("outputDirectory")?.toString() ?: "output" file("smithy-build.json").writeText(Node.prettyPrintJson(Node.objectNodeBuilder() .withMember("version", "1.0") From e93f24c5d24b09571a8090c7f14a871ecd654a14 Mon Sep 17 00:00:00 2001 From: kai lin Date: Wed, 28 Jan 2026 08:26:52 -0500 Subject: [PATCH 43/46] some services only exist in c2j and not smithy, added temporary solution to generate them. added patch for crt --- .../generators/templates/PaginationCodegenPlugin.java | 2 ++ .../smithy/codegen/cpp-pagination/build.gradle.kts | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java index 36d259a91685..6371f4d606eb 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/src/main/java/com/amazonaws/util/awsclientsmithygenerator/generators/templates/PaginationCodegenPlugin.java @@ -37,6 +37,7 @@ public void execute(PluginContext context) { // TODO: Remove this workaround - mock projections should use proper Smithy model generation // instead of manually writing files in the plugin + // Currently only needed for importexport, sdb (SimpleDB), and s3-crt // Check if this is a legacy service mock projection String projectionName = context.getProjectionName(); if (projectionName.endsWith(".mock")) { @@ -94,6 +95,7 @@ private void generateLegacyServiceFile(PluginContext context) { Map legacyServices = new HashMap<>(); legacyServices.put("importexport", "ImportExport"); legacyServices.put("sdb", "SimpleDB"); + legacyServices.put("s3-crt", "S3Crt"); String projectionName = context.getProjectionName(); String c2jName = projectionName.replace(".mock", ""); diff --git a/tools/code-generation/smithy/codegen/cpp-pagination/build.gradle.kts b/tools/code-generation/smithy/codegen/cpp-pagination/build.gradle.kts index 5a10c53e4afb..29c1ca217b7b 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination/build.gradle.kts +++ b/tools/code-generation/smithy/codegen/cpp-pagination/build.gradle.kts @@ -75,10 +75,11 @@ tasks.register("generate-smithy-build") { projectionsBuilder.withMember("$sdkId.${service.version.lowercase()}", projectionContents) } - // TODO: Remove this workaround - legacy services should have proper Smithy models + // TODO: Remove this workaround - legacy services should have proper Smithy model files // instead of hardcoding service names in both Gradle and Java + // Currently only needed for importexport, sdb (SimpleDB), and s3-crt // Add mock projections for legacy C2J-only services - val legacyServices = mapOf("importexport" to "ImportExport", "sdb" to "SimpleDB") + val legacyServices = mapOf("importexport" to "ImportExport", "sdb" to "SimpleDB", "s3-crt" to "S3Crt") legacyServices.forEach { (c2jName, pascalName) -> if (filteredServiceList.isEmpty() || c2jName in filteredServiceList) { val mockProjectionContents = Node.objectNodeBuilder() From fa6e021b27170502af13ee72eaa970fde622c622 Mon Sep 17 00:00:00 2001 From: kai lin Date: Fri, 30 Jan 2026 15:57:27 -0500 Subject: [PATCH 44/46] refactor the codegen so it looks like the workshop --- .../smithy/codegen/build.gradle.kts | 104 ++++++++++++++++++ .../codegen/cpp-pagination/build.gradle.kts | 104 ------------------ .../codegen/cpp-pagination/smithy-build.json | 36 ------ tools/scripts/codegen/pagination_gen.py | 25 +++-- 4 files changed, 119 insertions(+), 150 deletions(-) delete mode 100644 tools/code-generation/smithy/codegen/cpp-pagination/build.gradle.kts delete mode 100644 tools/code-generation/smithy/codegen/cpp-pagination/smithy-build.json diff --git a/tools/code-generation/smithy/codegen/build.gradle.kts b/tools/code-generation/smithy/codegen/build.gradle.kts index c619795943a2..0a90aa0be302 100644 --- a/tools/code-generation/smithy/codegen/build.gradle.kts +++ b/tools/code-generation/smithy/codegen/build.gradle.kts @@ -1,5 +1,15 @@ +import software.amazon.smithy.model.Model +import software.amazon.smithy.model.node.Node +import software.amazon.smithy.model.shapes.ServiceShape +import software.amazon.smithy.aws.traits.ServiceTrait +import org.gradle.api.logging.Logging +import kotlin.streams.toList + +val logger = Logging.getLogger("MyLogger") + plugins { id("java-library") + id("software.amazon.smithy.gradle.smithy-base").version("1.3.0") } repositories { @@ -12,5 +22,99 @@ allprojects { version = "0.1.0" } +buildscript { + dependencies { + classpath(codegen.model) + classpath(codegen.aws.traits) + classpath(codegen.rules.engine) + } +} + dependencies { + implementation(project(":cpp-pagination-codegen")) + implementation(codegen.aws.traits) + implementation(codegen.aws.cloudformation.traits) + implementation(codegen.aws.iam.traits) + implementation(codegen.aws.endpoints) + implementation(codegen.waiters) +} + +tasks.jar { + enabled = false +} + +// Generates a smithy-build.json with a projection for each service, including +// only that service's model. +tasks.register("generate-smithy-build") { + doLast { + val projectionsBuilder = Node.objectNodeBuilder() + val models = project.file("../api-descriptions") + val filteredServices: String = project.findProperty("servicesFilter")?.toString() ?: "" + val filteredServiceList = filteredServices.split(",").map { it.trim() }.filter { it.isNotEmpty() } + val c2jMapStr: String = project.findProperty("c2jMap")?.toString() ?: "" + + fileTree(models).filter { it.isFile }.files.forEach eachFile@{ file -> + val model = Model.assembler() + .addImport(file.absolutePath) + // Grab the result directly rather than worrying about checking for errors via unwrap. + // All we care about here is the service shape, any unchecked errors will be exposed + // as part of the actual build task done by the smithy gradle plugin. + .assemble().result.get() + val services = model.shapes(ServiceShape::class.java).sorted().toList() + if (services.size != 1) return@eachFile + + val service = services[0] + val serviceTrait = service.getTrait(ServiceTrait::class.java).get() + + // Clean up sdkId + val sdkId = serviceTrait.sdkId.replace(" ", "-").replace("_", "-").lowercase() + + // Filter by service id if necessary + if (filteredServiceList.isNotEmpty() && sdkId !in filteredServiceList) return@eachFile + + // Create projection contents + val projectionContents = Node.objectNodeBuilder() + .withMember("imports", Node.fromStrings("${models.absolutePath}${File.separator}${file.name}")) + .withMember("plugins", Node.objectNode() + .withMember("cpp-codegen-pagination-plugin", Node.objectNodeBuilder() + .withMember("c2jMap", Node.from(c2jMapStr)) + .build())) + .build() + + // Add the projection contents to the projections builder + projectionsBuilder.withMember("$sdkId.${service.version.lowercase()}", projectionContents) + } + + // TODO: Remove this workaround - legacy services should have proper Smithy model files + // instead of hardcoding service names in both Gradle and Java + // Currently only needed for importexport, sdb (SimpleDB), and s3-crt + // Add mock projections for legacy C2J-only services + val legacyServices = mapOf("importexport" to "ImportExport", "sdb" to "SimpleDB", "s3-crt" to "S3Crt") + legacyServices.forEach { (c2jName, pascalName) -> + if (filteredServiceList.isEmpty() || c2jName in filteredServiceList) { + val mockProjectionContents = Node.objectNodeBuilder() + .withMember("plugins", Node.objectNode() + .withMember("cpp-codegen-pagination-plugin", Node.objectNodeBuilder() + .withMember("c2jMap", Node.from(c2jMapStr)) + .build())) + .build() + projectionsBuilder.withMember("$c2jName.mock", mockProjectionContents) + } + } + + val outputDirectoryArg = project.findProperty("outputDirectory")?.toString() ?: "output" + file("smithy-build.json").writeText(Node.prettyPrintJson(Node.objectNodeBuilder() + .withMember("version", "1.0") + .withMember("projections", projectionsBuilder.build()) + .withMember("outputDirectory", outputDirectoryArg) + .build())) + } +} + +// Generate smithy-build.json before running the build +tasks["build"].dependsOn(tasks["generate-smithy-build"]) + +// Prevent cpp-smoke-tests from building when root build is invoked +project(":cpp-smoke-tests").tasks.configureEach { + enabled = false } \ No newline at end of file diff --git a/tools/code-generation/smithy/codegen/cpp-pagination/build.gradle.kts b/tools/code-generation/smithy/codegen/cpp-pagination/build.gradle.kts deleted file mode 100644 index 29c1ca217b7b..000000000000 --- a/tools/code-generation/smithy/codegen/cpp-pagination/build.gradle.kts +++ /dev/null @@ -1,104 +0,0 @@ -import software.amazon.smithy.model.Model -import software.amazon.smithy.model.node.Node -import software.amazon.smithy.model.shapes.ServiceShape -import software.amazon.smithy.aws.traits.ServiceTrait -import org.gradle.api.logging.Logging -import kotlin.streams.toList - -val logger = Logging.getLogger("MyLogger") - -plugins { - id("java-library") - id("software.amazon.smithy.gradle.smithy-base").version("1.3.0") -} - -repositories { - mavenLocal() - mavenCentral() -} - -buildscript { - dependencies { - classpath(codegen.model) - classpath(codegen.aws.traits) - classpath(codegen.rules.engine) - } -} - -dependencies { - implementation(project(":cpp-pagination-codegen")) - implementation(codegen.aws.traits) - implementation(codegen.aws.cloudformation.traits) - implementation(codegen.aws.iam.traits) - implementation(codegen.aws.endpoints) - implementation(codegen.smoke.test.traits) - implementation(codegen.aws.smoke.test.model) - implementation(codegen.waiters) -} - -tasks.jar { - enabled = false -} - -tasks.register("generate-smithy-build") { - doLast { - val projectionsBuilder = Node.objectNodeBuilder() - val models = project.file("../../api-descriptions") - val filteredServices: String = project.findProperty("servicesFilter")?.toString() ?: "" - val filteredServiceList = filteredServices.split(",").map { it.trim() }.filter { it.isNotEmpty() } - val c2jMapStr: String = project.findProperty("c2jMap")?.toString() ?: "" - - fileTree(models).filter { it.isFile }.files.forEach eachFile@{ file -> - val model = Model.assembler() - .addImport(file.absolutePath) - // Grab the result directly rather than worrying about checking for errors via unwrap. - // All we care about here is the service shape, any unchecked errors will be exposed - // as part of the actual build task done by the smithy gradle plugin. - .assemble().result.get() - val services = model.shapes(ServiceShape::class.java).sorted().toList() - if (services.size != 1) return@eachFile - - val service = services[0] - val serviceTrait = service.getTrait(ServiceTrait::class.java).get() - val sdkId = serviceTrait.sdkId.replace(" ", "-").replace("_", "-").lowercase() - - if (filteredServiceList.isNotEmpty() && sdkId !in filteredServiceList) return@eachFile - - val projectionContents = Node.objectNodeBuilder() - .withMember("imports", Node.fromStrings("${models.absolutePath}${File.separator}${file.name}")) - .withMember("plugins", Node.objectNode() - .withMember("cpp-codegen-pagination-plugin", Node.objectNodeBuilder() - .withMember("c2jMap", Node.from(c2jMapStr)) - .build())) - .build() - - projectionsBuilder.withMember("$sdkId.${service.version.lowercase()}", projectionContents) - } - - // TODO: Remove this workaround - legacy services should have proper Smithy model files - // instead of hardcoding service names in both Gradle and Java - // Currently only needed for importexport, sdb (SimpleDB), and s3-crt - // Add mock projections for legacy C2J-only services - val legacyServices = mapOf("importexport" to "ImportExport", "sdb" to "SimpleDB", "s3-crt" to "S3Crt") - legacyServices.forEach { (c2jName, pascalName) -> - if (filteredServiceList.isEmpty() || c2jName in filteredServiceList) { - val mockProjectionContents = Node.objectNodeBuilder() - .withMember("plugins", Node.objectNode() - .withMember("cpp-codegen-pagination-plugin", Node.objectNodeBuilder() - .withMember("c2jMap", Node.from(c2jMapStr)) - .build())) - .build() - projectionsBuilder.withMember("$c2jName.mock", mockProjectionContents) - } - } - - val outputDirectoryArg = project.findProperty("outputDirectory")?.toString() ?: "output" - file("smithy-build.json").writeText(Node.prettyPrintJson(Node.objectNodeBuilder() - .withMember("version", "1.0") - .withMember("projections", projectionsBuilder.build()) - .withMember("outputDirectory", outputDirectoryArg) - .build())) - } -} - -tasks["build"].dependsOn(tasks["generate-smithy-build"]) diff --git a/tools/code-generation/smithy/codegen/cpp-pagination/smithy-build.json b/tools/code-generation/smithy/codegen/cpp-pagination/smithy-build.json deleted file mode 100644 index 11f7416fb6a9..000000000000 --- a/tools/code-generation/smithy/codegen/cpp-pagination/smithy-build.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "version": "1.0", - "projections": { - "ec2.2016-11-15": { - "imports": [ - "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/ec2.json" - ], - "plugins": { - "cpp-codegen-pagination-plugin": { - "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" - } - } - }, - "s3.2006-03-01": { - "imports": [ - "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/s3.json" - ], - "plugins": { - "cpp-codegen-pagination-plugin": { - "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" - } - } - }, - "dynamodb.2012-08-10": { - "imports": [ - "/Users/cailinn/Desktop/workspace/aws-sdk-cpp/tools/code-generation/smithy/api-descriptions/dynamodb.json" - ], - "plugins": { - "cpp-codegen-pagination-plugin": { - "c2jMap": "{\"api-gateway\": \"apigateway\", \"application-auto-scaling\": \"application-autoscaling\", \"app-mesh\": \"appmesh\", \"auto-scaling\": \"autoscaling\", \"auto-scaling-plans\": \"autoscaling-plans\", \"cloudhsm-v2\": \"cloudhsmv2\", \"cloudsearch-domain\": \"cloudsearchdomain\", \"config-service\": \"config\", \"cost-and-usage-report-service\": \"cur\", \"data-pipeline\": \"datapipeline\", \"device-farm\": \"devicefarm\", \"direct-connect\": \"directconnect\", \"dynamodb-streams\": \"dynamodbstreams\", \"elastic-beanstalk\": \"elasticbeanstalk\", \"elastic-load-balancing\": \"elasticloadbalancing\", \"elastic-load-balancing-v2\": \"elasticloadbalancingv2\", \"global-accelerator\": \"globalaccelerator\", \"iot-1click-devices-service\": \"iot1click-devices\", \"iot-1click-projects\": \"iot1click-projects\", \"iot-data-plane\": \"iot-data\", \"iot-events-data\": \"iotevents-data\", \"iot-events\": \"iotevents\", \"iot-jobs-data-plane\": \"iot-jobs-data\", \"iot-wireless\": \"iotwireless\", \"kinesis-analytics\": \"kinesisanalytics\", \"kinesis-analytics-v2\": \"kinesisanalyticsv2\", \"kinesis-video\": \"kinesisvideo\", \"lex-models-v2\": \"lexv2-models\", \"lex-runtime-service\": \"lex\", \"lex-runtime-v2\": \"lexv2-runtime\", \"machine-learning\": \"machinelearning\", \"marketplace-commerce-analytics\": \"marketplacecommerceanalytics\", \"marketplace-entitlement-service\": \"marketplace-entitlement\", \"marketplace-metering\": \"meteringmarketplace\", \"migration-hub\": \"AWSMigrationHub\", \"mturk\": \"mturk-requester\", \"pinpoint-sms-voice\": \"sms-voice\", \"resource-groups-tagging-api\": \"resourcegroupstaggingapi\", \"route-53-domains\": \"route53domains\", \"route-53\": \"route53\", \"s3-control\": \"s3control\", \"sagemaker-runtime\": \"sagemaker-runtime\", \"secrets-manager\": \"secretsmanager\", \"serverlessapplicationrepository\": \"serverlessrepo\", \"service-catalog-appregistry\": \"servicecatalog-appregistry\", \"service-catalog\": \"servicecatalog\", \"transfer\": \"awstransfer\", \"cloudwatch\": \"monitoring\", \"cloudwatch-events\": \"events\", \"storage-gateway\": \"storagegateway\", \"efs\": \"elasticfilesystem\", \"emr\": \"elasticmapreduce\", \"ses\": \"email\", \"cognito-identity-provider\": \"cognito-idp\", \"cost-explorer\": \"ce\", \"application-discovery-service\": \"discovery\", \"database-migration-service\": \"dms\", \"sfn\": \"states\", \"lex-model-building-service\": \"lex-models\", \"cloudwatch-logs\": \"logs\", \"directory-service\": \"ds\", \"elasticsearch-service\": \"es\", \"importexport\": \"importexport\", \"sdb\": \"sdb\", \"transcribe-streaming\": \"transcribestreaming\"}" - } - } - } - }, - "outputDirectory": "output" -} \ No newline at end of file diff --git a/tools/scripts/codegen/pagination_gen.py b/tools/scripts/codegen/pagination_gen.py index 67f34153327f..a5ac782b8b2e 100644 --- a/tools/scripts/codegen/pagination_gen.py +++ b/tools/scripts/codegen/pagination_gen.py @@ -34,7 +34,7 @@ def generate(self, clients_to_build: set): if self._generate_pagination(smithy_services, json.dumps(self.smithy_c2j_data)): target_dir = os.path.abspath("generated/src") self._copy_cpp_codegen_contents( - os.path.abspath("tools/code-generation/smithy/codegen"), + os.path.abspath(SMITHY_GENERATOR_LOCATION), "cpp-codegen-pagination-plugin", target_dir ) @@ -44,7 +44,8 @@ def generate(self, clients_to_build: set): def _generate_pagination(self, smithy_services: List[str], smithy_c2j_data: str): smithy_codegen_command = [ "./gradlew", - ":cpp-pagination:build", + "clean", + "build", "-PservicesFilter=" + ",".join(smithy_services), "-Pc2jMap=" + smithy_c2j_data ] @@ -72,15 +73,15 @@ def _generate_pagination(self, smithy_services: List[str], smithy_c2j_data: str) return False def _copy_cpp_codegen_contents(self, top_level_dir: str, plugin_name: str, target_dir: str): - # Walk only cpp-pagination subdirectory to avoid .git and gradle cache - cpp_pagination_dir = os.path.join(top_level_dir, "cpp-pagination") + # Walk through the output directory to find plugin directories + output_dir = os.path.join(top_level_dir, "output") # TODO: Verify if this check is still needed after Smithy generator always creates output - if not os.path.exists(cpp_pagination_dir): + if not os.path.exists(output_dir): if self.debug: - print(f"No cpp-pagination directory found at '{cpp_pagination_dir}'") + print(f"No output directory found at '{output_dir}'") return - for root, dirs, files in os.walk(cpp_pagination_dir): + for root, dirs, files in os.walk(output_dir): if plugin_name in dirs: source_dir = os.path.join(root, plugin_name) @@ -117,10 +118,14 @@ def _copy_cpp_codegen_contents(self, top_level_dir: str, plugin_name: str, targe if self.debug: print(f"Copied from '{source_dir}' to '{service_target_dir}'") - # Cleanup output directory - output_dir = os.path.join(top_level_dir, "cpp-pagination/output") + # Cleanup output directory and smithy-build.json if os.path.exists(output_dir): shutil.rmtree(output_dir) if self.debug: print(f"Cleaned up '{output_dir}'") - + + smithy_build_json = os.path.join(top_level_dir, "smithy-build.json") + if os.path.exists(smithy_build_json): + os.remove(smithy_build_json) + if self.debug: + print(f"Cleaned up '{smithy_build_json}'") From a1143557271a6a2934432f63dcead1aea0c5305a Mon Sep 17 00:00:00 2001 From: kai lin Date: Sat, 31 Jan 2026 01:53:41 -0500 Subject: [PATCH 45/46] added smoke test pagination dependency --- tools/code-generation/smithy/codegen/build.gradle.kts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/code-generation/smithy/codegen/build.gradle.kts b/tools/code-generation/smithy/codegen/build.gradle.kts index 0a90aa0be302..dfb290f07475 100644 --- a/tools/code-generation/smithy/codegen/build.gradle.kts +++ b/tools/code-generation/smithy/codegen/build.gradle.kts @@ -26,6 +26,7 @@ buildscript { dependencies { classpath(codegen.model) classpath(codegen.aws.traits) + classpath(codegen.aws.smoke.test.model) classpath(codegen.rules.engine) } } @@ -37,6 +38,8 @@ dependencies { implementation(codegen.aws.iam.traits) implementation(codegen.aws.endpoints) implementation(codegen.waiters) + implementation(codegen.smoke.test.traits) + implementation(codegen.aws.smoke.test.model) } tasks.jar { From d17544d9958b150aa096d902787a469982989ed9 Mon Sep 17 00:00:00 2001 From: kai lin Date: Sat, 31 Jan 2026 09:16:49 -0500 Subject: [PATCH 46/46] reverted to have everything in pagination codegen --- .../smithy/codegen/build.gradle.kts | 102 ------------------ .../cpp-pagination-codegen/build.gradle.kts | 97 +++++++++++++++++ tools/scripts/codegen/pagination_gen.py | 10 +- 3 files changed, 102 insertions(+), 107 deletions(-) diff --git a/tools/code-generation/smithy/codegen/build.gradle.kts b/tools/code-generation/smithy/codegen/build.gradle.kts index dfb290f07475..dc71331fcaad 100644 --- a/tools/code-generation/smithy/codegen/build.gradle.kts +++ b/tools/code-generation/smithy/codegen/build.gradle.kts @@ -1,15 +1,5 @@ -import software.amazon.smithy.model.Model -import software.amazon.smithy.model.node.Node -import software.amazon.smithy.model.shapes.ServiceShape -import software.amazon.smithy.aws.traits.ServiceTrait -import org.gradle.api.logging.Logging -import kotlin.streams.toList - -val logger = Logging.getLogger("MyLogger") - plugins { id("java-library") - id("software.amazon.smithy.gradle.smithy-base").version("1.3.0") } repositories { @@ -22,101 +12,9 @@ allprojects { version = "0.1.0" } -buildscript { - dependencies { - classpath(codegen.model) - classpath(codegen.aws.traits) - classpath(codegen.aws.smoke.test.model) - classpath(codegen.rules.engine) - } -} - dependencies { - implementation(project(":cpp-pagination-codegen")) - implementation(codegen.aws.traits) - implementation(codegen.aws.cloudformation.traits) - implementation(codegen.aws.iam.traits) - implementation(codegen.aws.endpoints) - implementation(codegen.waiters) - implementation(codegen.smoke.test.traits) - implementation(codegen.aws.smoke.test.model) } -tasks.jar { - enabled = false -} - -// Generates a smithy-build.json with a projection for each service, including -// only that service's model. -tasks.register("generate-smithy-build") { - doLast { - val projectionsBuilder = Node.objectNodeBuilder() - val models = project.file("../api-descriptions") - val filteredServices: String = project.findProperty("servicesFilter")?.toString() ?: "" - val filteredServiceList = filteredServices.split(",").map { it.trim() }.filter { it.isNotEmpty() } - val c2jMapStr: String = project.findProperty("c2jMap")?.toString() ?: "" - - fileTree(models).filter { it.isFile }.files.forEach eachFile@{ file -> - val model = Model.assembler() - .addImport(file.absolutePath) - // Grab the result directly rather than worrying about checking for errors via unwrap. - // All we care about here is the service shape, any unchecked errors will be exposed - // as part of the actual build task done by the smithy gradle plugin. - .assemble().result.get() - val services = model.shapes(ServiceShape::class.java).sorted().toList() - if (services.size != 1) return@eachFile - - val service = services[0] - val serviceTrait = service.getTrait(ServiceTrait::class.java).get() - - // Clean up sdkId - val sdkId = serviceTrait.sdkId.replace(" ", "-").replace("_", "-").lowercase() - - // Filter by service id if necessary - if (filteredServiceList.isNotEmpty() && sdkId !in filteredServiceList) return@eachFile - - // Create projection contents - val projectionContents = Node.objectNodeBuilder() - .withMember("imports", Node.fromStrings("${models.absolutePath}${File.separator}${file.name}")) - .withMember("plugins", Node.objectNode() - .withMember("cpp-codegen-pagination-plugin", Node.objectNodeBuilder() - .withMember("c2jMap", Node.from(c2jMapStr)) - .build())) - .build() - - // Add the projection contents to the projections builder - projectionsBuilder.withMember("$sdkId.${service.version.lowercase()}", projectionContents) - } - - // TODO: Remove this workaround - legacy services should have proper Smithy model files - // instead of hardcoding service names in both Gradle and Java - // Currently only needed for importexport, sdb (SimpleDB), and s3-crt - // Add mock projections for legacy C2J-only services - val legacyServices = mapOf("importexport" to "ImportExport", "sdb" to "SimpleDB", "s3-crt" to "S3Crt") - legacyServices.forEach { (c2jName, pascalName) -> - if (filteredServiceList.isEmpty() || c2jName in filteredServiceList) { - val mockProjectionContents = Node.objectNodeBuilder() - .withMember("plugins", Node.objectNode() - .withMember("cpp-codegen-pagination-plugin", Node.objectNodeBuilder() - .withMember("c2jMap", Node.from(c2jMapStr)) - .build())) - .build() - projectionsBuilder.withMember("$c2jName.mock", mockProjectionContents) - } - } - - val outputDirectoryArg = project.findProperty("outputDirectory")?.toString() ?: "output" - file("smithy-build.json").writeText(Node.prettyPrintJson(Node.objectNodeBuilder() - .withMember("version", "1.0") - .withMember("projections", projectionsBuilder.build()) - .withMember("outputDirectory", outputDirectoryArg) - .build())) - } -} - -// Generate smithy-build.json before running the build -tasks["build"].dependsOn(tasks["generate-smithy-build"]) - // Prevent cpp-smoke-tests from building when root build is invoked project(":cpp-smoke-tests").tasks.configureEach { enabled = false diff --git a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/build.gradle.kts b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/build.gradle.kts index d929cca7cbb1..682fdc217a0d 100644 --- a/tools/code-generation/smithy/codegen/cpp-pagination-codegen/build.gradle.kts +++ b/tools/code-generation/smithy/codegen/cpp-pagination-codegen/build.gradle.kts @@ -1,3 +1,12 @@ +import software.amazon.smithy.model.Model +import software.amazon.smithy.model.node.Node +import software.amazon.smithy.model.shapes.ServiceShape +import software.amazon.smithy.aws.traits.ServiceTrait +import org.gradle.api.logging.Logging +import kotlin.streams.toList + +val logger = Logging.getLogger("MyLogger") + plugins { `java-library` } @@ -7,6 +16,15 @@ repositories { mavenCentral() } +buildscript { + dependencies { + classpath("software.amazon.smithy:smithy-model:1.51.0") + classpath("software.amazon.smithy:smithy-aws-traits:1.51.0") + classpath("software.amazon.smithy:smithy-aws-smoke-test-model:1.51.0") + classpath("software.amazon.smithy:smithy-rules-engine:1.51.0") + } +} + dependencies { implementation("software.amazon.smithy:smithy-model:1.51.0") implementation("software.amazon.smithy:smithy-codegen-core:1.51.0") @@ -15,4 +33,83 @@ dependencies { implementation("software.amazon.smithy:smithy-rules-engine:1.51.0") implementation("software.amazon.smithy:smithy-aws-endpoints:1.51.0") implementation("software.amazon.smithy:smithy-aws-iam-traits:1.51.0") + implementation("software.amazon.smithy:smithy-smoke-test-traits:1.51.0") + implementation("software.amazon.smithy:smithy-aws-smoke-test-model:1.51.0") +} + +tasks.jar { + enabled = true } + +// Generates a smithy-build.json with a projection for each service, including +// only that service's model. +tasks.register("generate-smithy-build") { + doLast { + val projectionsBuilder = Node.objectNodeBuilder() + val models = project.file("../../api-descriptions") + val filteredServices: String = project.findProperty("servicesFilter")?.toString() ?: "" + val filteredServiceList = filteredServices.split(",").map { it.trim() }.filter { it.isNotEmpty() } + val c2jMapStr: String = project.findProperty("c2jMap")?.toString() ?: "" + + fileTree(models).filter { it.isFile }.files.forEach eachFile@{ file -> + // Quick check: if we have a service filter, try to match by filename first + if (filteredServiceList.isNotEmpty()) { + val fileName = file.nameWithoutExtension.lowercase() + val matchesFilter = filteredServiceList.any { service -> + fileName == service.lowercase() || fileName == service.replace("-", "").lowercase() + } + if (!matchesFilter) return@eachFile + } + + val model = Model.assembler() + .addImport(file.absolutePath) + .assemble().result.get() + val services = model.shapes(ServiceShape::class.java).sorted().toList() + if (services.size != 1) return@eachFile + + val service = services[0] + val serviceTrait = service.getTrait(ServiceTrait::class.java).get() + + // Clean up sdkId + val sdkId = serviceTrait.sdkId.replace(" ", "-").replace("_", "-").lowercase() + + // Filter by service id if necessary + if (filteredServiceList.isNotEmpty() && sdkId !in filteredServiceList) return@eachFile + + // Create projection contents + val projectionContents = Node.objectNodeBuilder() + .withMember("imports", Node.fromStrings("${models.absolutePath}${File.separator}${file.name}")) + .withMember("plugins", Node.objectNode() + .withMember("cpp-codegen-pagination-plugin", Node.objectNodeBuilder() + .withMember("c2jMap", Node.from(c2jMapStr)) + .build())) + .build() + + // Add the projection contents to the projections builder + projectionsBuilder.withMember("$sdkId.${service.version.lowercase()}", projectionContents) + } + + // Add mock projections for legacy C2J-only services + val legacyServices = mapOf("importexport" to "ImportExport", "sdb" to "SimpleDB", "s3-crt" to "S3Crt") + legacyServices.forEach { (c2jName, pascalName) -> + if (filteredServiceList.isEmpty() || c2jName in filteredServiceList) { + val mockProjectionContents = Node.objectNodeBuilder() + .withMember("plugins", Node.objectNode() + .withMember("cpp-codegen-pagination-plugin", Node.objectNodeBuilder() + .withMember("c2jMap", Node.from(c2jMapStr)) + .build())) + .build() + projectionsBuilder.withMember("$c2jName.mock", mockProjectionContents) + } + } + + val outputDirectoryArg = project.findProperty("outputDirectory")?.toString() ?: "output" + file("smithy-build.json").writeText(Node.prettyPrintJson(Node.objectNodeBuilder() + .withMember("version", "1.0") + .withMember("projections", projectionsBuilder.build()) + .withMember("outputDirectory", outputDirectoryArg) + .build())) + } +} + +tasks["build"].dependsOn(tasks["generate-smithy-build"]) diff --git a/tools/scripts/codegen/pagination_gen.py b/tools/scripts/codegen/pagination_gen.py index a5ac782b8b2e..678ce096f6b7 100644 --- a/tools/scripts/codegen/pagination_gen.py +++ b/tools/scripts/codegen/pagination_gen.py @@ -44,8 +44,8 @@ def generate(self, clients_to_build: set): def _generate_pagination(self, smithy_services: List[str], smithy_c2j_data: str): smithy_codegen_command = [ "./gradlew", - "clean", - "build", + ":cpp-pagination-codegen:clean", + ":cpp-pagination-codegen:build", "-PservicesFilter=" + ",".join(smithy_services), "-Pc2jMap=" + smithy_c2j_data ] @@ -73,8 +73,8 @@ def _generate_pagination(self, smithy_services: List[str], smithy_c2j_data: str) return False def _copy_cpp_codegen_contents(self, top_level_dir: str, plugin_name: str, target_dir: str): - # Walk through the output directory to find plugin directories - output_dir = os.path.join(top_level_dir, "output") + # Walk through the cpp-pagination-codegen output directory to find plugin directories + output_dir = os.path.join(top_level_dir, "cpp-pagination-codegen", "output") # TODO: Verify if this check is still needed after Smithy generator always creates output if not os.path.exists(output_dir): if self.debug: @@ -124,7 +124,7 @@ def _copy_cpp_codegen_contents(self, top_level_dir: str, plugin_name: str, targe if self.debug: print(f"Cleaned up '{output_dir}'") - smithy_build_json = os.path.join(top_level_dir, "smithy-build.json") + smithy_build_json = os.path.join(top_level_dir, "cpp-pagination-codegen", "smithy-build.json") if os.path.exists(smithy_build_json): os.remove(smithy_build_json) if self.debug: