diff --git a/src/aws-cpp-sdk-core/include/aws/core/utils/json/JsonSerializer.h b/src/aws-cpp-sdk-core/include/aws/core/utils/json/JsonSerializer.h index 8b2ccc139bb5..ae98f6c18ff9 100644 --- a/src/aws-cpp-sdk-core/include/aws/core/utils/json/JsonSerializer.h +++ b/src/aws-cpp-sdk-core/include/aws/core/utils/json/JsonSerializer.h @@ -94,6 +94,12 @@ namespace Aws JsonValue& WithString(const Aws::String& key, const Aws::String& value); JsonValue& WithString(const char* key, const Aws::String& value); + /** + * Adds a null value to the top level of this node with key. + */ + JsonValue& WithNull(const Aws::String& key); + JsonValue& WithNull(const char* key); + /** * Converts the current JSON node to a string. */ diff --git a/src/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp b/src/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp index 3cdcac1a8127..bbf44e5b57de 100644 --- a/src/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp +++ b/src/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp @@ -153,6 +153,23 @@ JsonValue& JsonValue::WithString(const Aws::String& key, const Aws::String& valu return WithString(key.c_str(), value); } +JsonValue& JsonValue::WithNull(const char* key) +{ + if (!m_value) + { + m_value = cJSON_AS4CPP_CreateObject(); + } + + const auto val = cJSON_AS4CPP_CreateNull(); + AddOrReplace(m_value, key, val); + return *this; +} + +JsonValue& JsonValue::WithNull(const Aws::String& key) +{ + return WithNull(key.c_str()); +} + JsonValue& JsonValue::AsString(const Aws::String& value) { Destroy(); diff --git a/tests/aws-cpp-sdk-core-tests/utils/json/JsonSerializerTest.cpp b/tests/aws-cpp-sdk-core-tests/utils/json/JsonSerializerTest.cpp index 12234707833f..00f313f9752d 100644 --- a/tests/aws-cpp-sdk-core-tests/utils/json/JsonSerializerTest.cpp +++ b/tests/aws-cpp-sdk-core-tests/utils/json/JsonSerializerTest.cpp @@ -434,6 +434,39 @@ TEST_F(JsonSerializerTest, TestGetAllObjects) ASSERT_EQ(42, all["Key2"].AsInteger()); } +TEST_F(JsonSerializerTest, TestWithNull) +{ + JsonValue value; + value.WithString("Key1", "value1"); + value.WithNull("Key2"); + value.WithNull(Aws::String("Key3")); + value.WithInteger("Key4", 42); + + auto view = value.View(); + + ASSERT_TRUE(view.KeyExists("Key2")); + ASSERT_FALSE(view.ValueExists("Key2")); + ASSERT_TRUE(view.GetObject("Key2").IsNull()); + + ASSERT_TRUE(view.KeyExists("Key3")); + ASSERT_FALSE(view.ValueExists("Key3")); + ASSERT_TRUE(view.GetObject("Key3").IsNull()); + + ASSERT_STREQ("value1", view.GetString("Key1").c_str()); + ASSERT_EQ(42, view.GetInteger("Key4")); + + Aws::String serialized = view.WriteCompact(); + JsonValue reparsed(serialized); + ASSERT_TRUE(reparsed.WasParseSuccessful()); + auto reparsedView = reparsed.View(); + ASSERT_TRUE(reparsedView.KeyExists("Key2")); + ASSERT_FALSE(reparsedView.ValueExists("Key2")); + ASSERT_TRUE(reparsedView.GetObject("Key2").IsNull()); + ASSERT_TRUE(reparsedView.KeyExists("Key3")); + ASSERT_FALSE(reparsedView.ValueExists("Key3")); + ASSERT_TRUE(reparsedView.GetObject("Key3").IsNull()); +} + TEST_F(JsonSerializerTest, TestEquality) { auto input = R"({"AWS" : { diff --git a/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/c2j/C2jShape.java b/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/c2j/C2jShape.java index fdcde4780145..af13deb827bb 100644 --- a/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/c2j/C2jShape.java +++ b/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/c2j/C2jShape.java @@ -36,4 +36,5 @@ public class C2jShape { private boolean sensitive; private boolean document; private Map retryable; + private boolean sparse; } diff --git a/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/codegeneration/Shape.java b/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/codegeneration/Shape.java index fe953ce7a6b7..478056141298 100644 --- a/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/codegeneration/Shape.java +++ b/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/codegeneration/Shape.java @@ -63,6 +63,7 @@ public class Shape { private boolean overrideStreaming = false; private boolean requestCompressionRequired=false; private boolean requestCompressionRequiredGzip=false; + private boolean sparse=false; public boolean isMap() { return "map".equals(type.toLowerCase()); diff --git a/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/codegeneration/cpp/CppShapeInformation.java b/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/codegeneration/cpp/CppShapeInformation.java index 4ca717849337..9e91eac943e0 100644 --- a/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/codegeneration/cpp/CppShapeInformation.java +++ b/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/codegeneration/cpp/CppShapeInformation.java @@ -31,11 +31,15 @@ public class CppShapeInformation { private final String requestContentType; public CppShapeInformation(final Shape shape, final ServiceModel serviceModel) { + this(shape, serviceModel, CppViewHelper.computeCppType(shape)); + } + + public CppShapeInformation(final Shape shape, final ServiceModel serviceModel, final String cppType) { this.shape = shape; this.serviceModel = serviceModel; className = shape.getName(); exportValue = CppViewHelper.computeExportValue(serviceModel.getMetadata().getClassNamePrefix()); - cppType = CppViewHelper.computeCppType(shape); + this.cppType = cppType; headerIncludes = CppViewHelper.computeHeaderIncludes(serviceModel.getMetadata().getProjectName(), shape); sourceIncludes = CppViewHelper.computeSourceIncludes(serviceModel.getMetadata().getProjectName(), shape); sourceIncludes.removeAll(headerIncludes); diff --git a/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/codegeneration/cpp/CppViewHelper.java b/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/codegeneration/cpp/CppViewHelper.java index 9c215a955ca3..46ec36646c32 100644 --- a/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/codegeneration/cpp/CppViewHelper.java +++ b/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/codegeneration/cpp/CppViewHelper.java @@ -225,12 +225,18 @@ else if(shape.isStructure() || shape.isEnum()) else if(shape.isList()) { String type = computeCppTypeInternal(shape.getListMember().getShape(), typeMapping); + if (shape.isSparse()) { + return String.format("Aws::Vector>", type); + } return String.format("Aws::Vector<%s>", type); } else if(shape.isMap()) { String key = computeCppTypeInternal(shape.getMapKey().getShape(), typeMapping); String value = computeCppTypeInternal(shape.getMapValue().getShape(), typeMapping); + if (shape.isSparse()) { + return String.format("Aws::Map<%s, Aws::Crt::Optional<%s>>", key, value); + } return String.format("Aws::Map<%s, %s>", key, value); } @@ -387,6 +393,9 @@ public static Set computeHeaderIncludes(String projectName, Shape shape) headers.add(formatModelIncludeName(projectName, shapeInList)); } } + if (next.isSparse()) { + headers.add(""); + } if(!next.isPrimitive()) { if (next.isException() && !next.isModeledException()) { // C++ SDK code generator skips generating exceptions that can be expressed using diff --git a/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/generators/cpp/CborCppClientGenerator.java b/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/generators/cpp/CborCppClientGenerator.java index 30a999a3c034..8004ca6718bd 100644 --- a/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/generators/cpp/CborCppClientGenerator.java +++ b/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/generators/cpp/CborCppClientGenerator.java @@ -13,6 +13,7 @@ import com.amazonaws.util.awsclientgenerator.domainmodels.codegeneration.cpp.CppCborViewHelper; import com.amazonaws.util.awsclientgenerator.domainmodels.codegeneration.cpp.CppShapeInformation; import com.amazonaws.util.awsclientgenerator.domainmodels.codegeneration.cpp.CppViewHelper; +import org.apache.commons.lang3.tuple.Pair; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; @@ -30,6 +31,18 @@ public CborCppClientGenerator() throws Exception { super(); } + @Override + protected Map buildShapeInformationCache(final ServiceModel serviceModel) { + return serviceModel.getShapes().values().stream() + .map(shape -> Pair.of(shape.getName(), new CppShapeInformation(shape, serviceModel, CppCborViewHelper.computeCppType(shape)))) + .collect(Collectors.toMap(Pair::getKey, Pair::getValue)); + } + + @Override + protected Class getViewHelperClass() { + return CppCborViewHelper.class; + } + @Override protected SdkFileEntry generateErrorMarshallerHeaderFile(ServiceModel serviceModel) throws Exception { Template template = velocityEngine.getTemplate("/com/amazonaws/util/awsclientgenerator/velocity/cpp/cbor/CborErrorMarshallerHeader.vm", StandardCharsets.UTF_8.name()); @@ -78,7 +91,7 @@ protected SdkFileEntry generateModelHeaderFile(ServiceModel serviceModel, Map.En } context.put("shape", shape); - context.put("typeInfo", new CppShapeInformation(shape, serviceModel)); + context.put("typeInfo", new CppShapeInformation(shape, serviceModel, CppCborViewHelper.computeCppType(shape))); context.put("CppViewHelper", CppCborViewHelper.class); String fileName = String.format("include/aws/%s/model/%s.h", serviceModel.getMetadata().getProjectName(), @@ -149,7 +162,7 @@ else if (shape.isResult()) { } context.put("shape", shape); - context.put("typeInfo", new CppShapeInformation(shape, serviceModel)); + context.put("typeInfo", new CppShapeInformation(shape, serviceModel, CppCborViewHelper.computeCppType(shape))); context.put("CppViewHelper", CppCborViewHelper.class); String fileName = String.format("source/model/%s.cpp", shapeEntry.getKey()); diff --git a/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/generators/cpp/CppClientGenerator.java b/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/generators/cpp/CppClientGenerator.java index edefbb2045a8..4cdf5f7c7968 100644 --- a/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/generators/cpp/CppClientGenerator.java +++ b/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/generators/cpp/CppClientGenerator.java @@ -88,9 +88,7 @@ public SdkFileEntry[] generateSourceFiles(ServiceModel serviceModel) throws Exce addEventStreamInitialResponse(serviceModel); addRequestIdToResults(serviceModel); List fileList = new ArrayList<>(); - final Map shapeInformationCache = serviceModel.getShapes().values().stream() - .map(shape -> Pair.of(shape.getName(), new CppShapeInformation(shape, serviceModel))) - .collect(Collectors.toMap(Pair::getKey, Pair::getValue)); + final Map shapeInformationCache = buildShapeInformationCache(serviceModel); fileList.addAll(generateModelHeaderFiles(serviceModel, shapeInformationCache)); fileList.addAll(generateModelSourceFiles(serviceModel, shapeInformationCache)); fileList.add(generateClientHeaderFile(serviceModel)); @@ -256,6 +254,16 @@ private void CheckAndEnableSigV4A(final ServiceModel serviceModel, VelocityConte } } + protected Map buildShapeInformationCache(final ServiceModel serviceModel) { + return serviceModel.getShapes().values().stream() + .map(shape -> Pair.of(shape.getName(), new CppShapeInformation(shape, serviceModel))) + .collect(Collectors.toMap(Pair::getKey, Pair::getValue)); + } + + protected Class getViewHelperClass() { + return CppViewHelper.class; + } + protected final VelocityContext createContext(final ServiceModel serviceModel) { VelocityContext context = new VelocityContext(); context.put("nl", System.lineSeparator()); @@ -326,7 +334,7 @@ else if (shape.isEvent() && "blob".equals(shape.getEventPayloadType())) { } context.put("shape", shape); context.put("typeInfo", shapeInformationCache.get(shape.getName())); - context.put("CppViewHelper", CppViewHelper.class); + context.put("CppViewHelper", getViewHelperClass()); String fileName = String.format("include/aws/%s/model/%s.h", serviceModel.getMetadata().getProjectName(), shapeEntry.getKey()); diff --git a/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/transform/C2jModelToGeneratorModelTransformer.java b/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/transform/C2jModelToGeneratorModelTransformer.java index 1838d2c7b59a..89ed4e05ab95 100644 --- a/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/transform/C2jModelToGeneratorModelTransformer.java +++ b/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/transform/C2jModelToGeneratorModelTransformer.java @@ -439,6 +439,10 @@ Shape convertShapeBasics(C2jShape c2jShape, String shapeName) { shape.setEvent(c2jShape.isEvent()); shape.setException(c2jShape.isException()); shape.setDocument(c2jShape.isDocument()); + shape.setSparse(c2jShape.isSparse()); + if (shape.isSparse() && !shape.isList() && !shape.isMap()) { + throw new SourceGenerationFailedException("The sparse trait is only applicable to list and map shapes, but was found on shape: " + shape.getName()); + } if (c2jShape.getXmlNamespace() != null) { XmlNamespace xmlns = new XmlNamespace(); @@ -850,6 +854,7 @@ Shape cloneShape(Shape shape) { cloned.setException(shape.isException()); cloned.setXmlNamespace(shape.getXmlNamespace()); cloned.setDocument(shape.isDocument()); + cloned.setSparse(shape.isSparse()); return cloned; } diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/ModelClassHeaderMembersSource.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/ModelClassHeaderMembersSource.vm index ba5ccc5bed0a..de43e1bd99a8 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/ModelClassHeaderMembersSource.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/ModelClassHeaderMembersSource.vm @@ -42,7 +42,11 @@ ${spaces}for(const auto& item : $memberVarName) ${spaces}{ ${spaces} ss << "${locationName}" << item.first; +#if($member.shape.sparse) + ${spaces} if(item.second.has_value()) { headers.emplace(ss.str(), item.second.value()); } +#else ${spaces} headers.emplace(ss.str(), item.second); +#end ${spaces} ss.str(""); ${spaces}} #elseif($member.shape.list) diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/ModelClassMembersAndInlines.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/ModelClassMembersAndInlines.vm index 19804fce8c45..5af591b469a0 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/ModelClassMembersAndInlines.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/ModelClassMembersAndInlines.vm @@ -111,6 +111,24 @@ #set($mapMember = $member.value.shape) #set($keyType = $CppViewHelper.computeCppType($mapMember.mapKey.shape)) #set($valueType = $CppViewHelper.computeCppType($mapMember.mapValue.shape)) +#if($mapMember.sparse) +#set($optionalValueType = "Aws::Crt::Optional<${valueType}>") +#if(!$mapMember.mapKey.shape.primitive && !$mapMember.mapKey.shape.enum && !$mapMember.mapValue.shape.primitive && !$mapMember.mapValue.shape.enum) +#set($keyTemplType = "${memberKeyWithFirstLetterCapitalized}KeyT") +#set($valueTemplType = "${memberKeyWithFirstLetterCapitalized}ValueT") + template + ${classNameRef} Add${memberKeyWithFirstLetterCapitalized}(${keyTemplType}&& key, ${valueTemplType}&& value) { + ${setHasBeenSet}${memberVariableName}.emplace(std::forward<${keyTemplType}>(key), std::forward<${valueTemplType}>(value)); return *this; + } +#else + ${inline}${classNameRef} Add${memberKeyWithFirstLetterCapitalized}(${keyType} key, ${valueType} value) { + ${setHasBeenSet}${memberVariableName}.emplace(key, value); return *this; + } +#end + ${inline}${classNameRef} Add${memberKeyWithFirstLetterCapitalized}(${keyType} key, ${optionalValueType} value) { + ${setHasBeenSet}${memberVariableName}.emplace(key, value); return *this; + } +#else #if(!$mapMember.mapKey.shape.primitive && !$mapMember.mapKey.shape.enum && !$mapMember.mapValue.shape.primitive && !$mapMember.mapValue.shape.enum) #set($keyTemplType = "${memberKeyWithFirstLetterCapitalized}KeyT") #set($valueTemplType = "${memberKeyWithFirstLetterCapitalized}ValueT") @@ -124,9 +142,21 @@ } #end #end +#end #if($member.value.shape.list) #set($listMember = $member.value.shape) #set($valueType = $CppViewHelper.computeCppType($listMember.listMember.shape)) +#if($listMember.sparse) +#set($optionalValueType = "Aws::Crt::Optional<${valueType}>") +#if(!$listMember.listMember.shape.primitive && !$listMember.listMember.shape.enum) +#set($valueTemplType = "${memberKeyWithFirstLetterCapitalized}T") + template + ${classNameRef} Add${memberKeyWithFirstLetterCapitalized}(${valueTemplType}&& value) { ${setHasBeenSet}${memberVariableName}.emplace_back(std::forward<${valueTemplType}>(value)); return *this; } +#else + ${inline}${classNameRef} Add${memberKeyWithFirstLetterCapitalized}(${valueType} value)$adderWithCopy +#end + ${inline}${classNameRef} Add${memberKeyWithFirstLetterCapitalized}(${optionalValueType} value)$adderWithCopy +#else #if(!$listMember.listMember.shape.primitive && !$listMember.listMember.shape.enum) #set($valueTemplType = "${memberKeyWithFirstLetterCapitalized}T") template @@ -134,6 +164,7 @@ #else ${inline}${classNameRef} Add${memberKeyWithFirstLetterCapitalized}(${valueType} value)$adderWithCopy #end +#end #end ///@} #end##if(!($CppViewHelper.isStreamingPayloadMember($shape, $member.key) && $shape.request)) diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/cbor/CborDecodeListValue.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/cbor/CborDecodeListValue.vm index 9a47a159e28b..6474947eaa89 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/cbor/CborDecodeListValue.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/cbor/CborDecodeListValue.vm @@ -1,7 +1,24 @@ +#set($parentListDepth = $recursionDepth - 1) +#if($member.shape.sparse) +{ + auto nullPeek_${recursionDepth} = decoder->PeekType(); + if (nullPeek_${recursionDepth}.has_value() && nullPeek_${recursionDepth}.value() == Aws::Crt::Cbor::CborType::Null) { + decoder->ConsumeNextSingleElement(); +#if($parentListDepth == 0) + ${memberVarName}.emplace_back(); +#else + nestedList_${parentListDepth}.emplace_back(); +#end + } else { +#end #if($shapeMember.enum) auto ${containerVar} = decoder->PopNextTextVal(); if (${containerVar}.has_value()) { - ${value}.push_back(${shapeMember.name}Mapper::Get${shapeMember.name}ForName(Aws::String(reinterpret_cast(${containerVar}.value().ptr), ${containerVar}.value().len))); +#if($parentListDepth == 0) + ${memberVarName}.push_back(${shapeMember.name}Mapper::Get${shapeMember.name}ForName(Aws::String(reinterpret_cast(${containerVar}.value().ptr), ${containerVar}.value().len))); +#else + nestedList_${parentListDepth}.push_back(${shapeMember.name}Mapper::Get${shapeMember.name}ForName(Aws::String(reinterpret_cast(${containerVar}.value().ptr), ${containerVar}.value().len))); +#end } #elseif($shapeMember.string) auto peekType_${recursionDepth} = decoder->PeekType(); @@ -9,7 +26,11 @@ if(peekType_${recursionDepth}.has_value()){ if (peekType_${recursionDepth}.value() == Aws::Crt::Cbor::CborType::Text) { auto ${containerVar} = decoder->PopNextTextVal(); if (${containerVar}.has_value()) { - ${value}.push_back(Aws::String(reinterpret_cast(${containerVar}.value().ptr), ${containerVar}.value().len)); +#if($parentListDepth == 0) + ${memberVarName}.push_back(Aws::String(reinterpret_cast(${containerVar}.value().ptr), ${containerVar}.value().len)); +#else + nestedList_${parentListDepth}.push_back(Aws::String(reinterpret_cast(${containerVar}.value().ptr), ${containerVar}.value().len)); +#end } } else { decoder->ConsumeNextSingleElement(); @@ -27,24 +48,40 @@ if(peekType_${recursionDepth}.has_value()){ ss_${recursionDepth} << Aws::String(reinterpret_cast(${containerVar}.value().ptr), ${containerVar}.value().len); } } - ${value}.push_back(ss_${recursionDepth}.str()); +#if($parentListDepth == 0) + ${memberVarName}.push_back(ss_${recursionDepth}.str()); +#else + nestedList_${parentListDepth}.push_back(ss_${recursionDepth}.str()); +#end ss_${recursionDepth}.clear(); } } #elseif($shapeMember.boolean) auto ${containerVar} = decoder->PopNextBooleanVal(); if (${containerVar}.has_value()) { - ${value}.push_back(${containerVar}.value()); +#if($parentListDepth == 0) + ${memberVarName}.push_back(${containerVar}.value()); +#else + nestedList_${parentListDepth}.push_back(${containerVar}.value()); +#end } #elseif($shapeMember.double) auto ${containerVar} = decoder->PopNextFloatVal(); if (${containerVar}.has_value()) { - ${value}.push_back(${containerVar}.value()); +#if($parentListDepth == 0) + ${memberVarName}.push_back(${containerVar}.value()); +#else + nestedList_${parentListDepth}.push_back(${containerVar}.value()); +#end } #elseif($shapeMember.float) auto ${containerVar} = decoder->PopNextFloatVal(); if (${containerVar}.has_value()) { - ${value}.push_back(${containerVar}.value()); +#if($parentListDepth == 0) + ${memberVarName}.push_back(${containerVar}.value()); +#else + nestedList_${parentListDepth}.push_back(${containerVar}.value()); +#end } #elseif($shapeMember.blob) auto peekType_${recursionDepth} = decoder->PeekType(); @@ -52,7 +89,11 @@ if(peekType_${recursionDepth}.has_value()){ if (peekType_${recursionDepth}.value() == Aws::Crt::Cbor::CborType::Bytes) { auto ${containerVar} = decoder->PopNextBytesVal(); if (${containerVar}.has_value()) { - ${value}.push_back(Aws::Utils::ByteBuffer(${containerVar}.value().ptr, ${containerVar}.value().len)); +#if($parentListDepth == 0) + ${memberVarName}.push_back(Aws::Utils::ByteBuffer(${containerVar}.value().ptr, ${containerVar}.value().len)); +#else + nestedList_${parentListDepth}.push_back(Aws::Utils::ByteBuffer(${containerVar}.value().ptr, ${containerVar}.value().len)); +#end } } else { decoder->ConsumeNextSingleElement(); @@ -70,7 +111,11 @@ if(peekType_${recursionDepth}.has_value()){ ss_${recursionDepth} << Aws::String(reinterpret_cast(${containerVar}.value().ptr), ${containerVar}.value().len); } } - ${value}.push_back(Aws::Utils::ByteBuffer(ss_${recursionDepth}.str())); +#if($parentListDepth == 0) + ${memberVarName}.push_back(Aws::Utils::ByteBuffer(ss_${recursionDepth}.str())); +#else + nestedList_${parentListDepth}.push_back(Aws::Utils::ByteBuffer(ss_${recursionDepth}.str())); +#end ss_${recursionDepth}.clear(); } } @@ -85,23 +130,39 @@ if(peekType_${recursionDepth}.has_value()){ { auto ${containerVar} = decoder->PopNextFloatVal(); if (${containerVar}.has_value()) { - ${value}.push_back(Aws::Utils::DateTime(${containerVar}.value())); +#if($parentListDepth == 0) + ${memberVarName}.push_back(Aws::Utils::DateTime(${containerVar}.value())); +#else + nestedList_${parentListDepth}.push_back(Aws::Utils::DateTime(${containerVar}.value())); +#end } } else { auto ${containerVar} = decoder->PopNextUnsignedIntVal(); if (${containerVar}.has_value()) { - ${value}.push_back(Aws::Utils::DateTime(${containerVar}.value())); +#if($parentListDepth == 0) + ${memberVarName}.push_back(Aws::Utils::DateTime(${containerVar}.value())); +#else + nestedList_${parentListDepth}.push_back(Aws::Utils::DateTime(${containerVar}.value())); +#end } } } } #elseif($shapeMember.structure) #if($member.shape.isMutuallyReferencedWith($shape) || $member.shape.getName() == $shape.getName()) - ${value}.push_back(Aws::MakeShared<${shapeMember.name}>("${typeInfo.className}", ${shapeMember.name}(decoder))); +#if($parentListDepth == 0) + ${memberVarName}.push_back(Aws::MakeShared<${shapeMember.name}>("${typeInfo.className}", ${shapeMember.name}(decoder))); +#else + nestedList_${parentListDepth}.push_back(Aws::MakeShared<${shapeMember.name}>("${typeInfo.className}", ${shapeMember.name}(decoder))); +#end #else - ${value}.push_back(${shapeMember.name}(decoder)); +#if($parentListDepth == 0) + ${memberVarName}.push_back(${shapeMember.name}(decoder)); +#else + nestedList_${parentListDepth}.push_back(${shapeMember.name}(decoder)); +#end #end #elseif($shapeMember.list) #set($template.nestedShapeMember = $shapeMember.listMember.shape) @@ -145,7 +206,7 @@ if(peekType_${recursionDepth}.has_value()){ } #if($recursionDepth > 1) #set($parentDepth = $recursionDepth - 1) - nestedList_${parentDepth}.push_back(${value}); + nestedList_${parentDepth}.push_back(nestedList_${recursionDepth}); #else ${memberVarName}.push_back(nestedList_${recursionDepth}); #end @@ -191,7 +252,7 @@ if(peekType_${recursionDepth}.has_value()){ } #if($recursionDepth > 1) #set($parentDepth = $recursionDepth - 1) - nestedList_${parentDepth}.push_back(${value}); + nestedList_${parentDepth}.push_back(nestedMap_${recursionDepth}); #else ${memberVarName}.push_back(nestedMap_${recursionDepth}); #end @@ -202,13 +263,25 @@ if(peekType_${recursionDepth}.has_value()){ if(peekType_${recursionDepth}.value() == Aws::Crt::Cbor::CborType::UInt){ auto ${containerVar} = decoder->PopNextUnsignedIntVal(); if (${containerVar}.has_value()) { - ${value}.push_back(static_cast(${containerVar}.value())); +#if($parentListDepth == 0) + ${memberVarName}.push_back(static_cast(${containerVar}.value())); +#else + nestedList_${parentListDepth}.push_back(static_cast(${containerVar}.value())); +#end } } else { auto ${containerVar} = decoder->PopNextNegativeIntVal(); if (${containerVar}.has_value()) { - ${value}.push_back(static_cast(1 - ${containerVar}.value())); +#if($parentListDepth == 0) + ${memberVarName}.push_back(static_cast(1 - ${containerVar}.value())); +#else + nestedList_${parentListDepth}.push_back(static_cast(1 - ${containerVar}.value())); +#end } } } -#end \ No newline at end of file +#end +#if($member.shape.sparse) + } // end else (non-null sparse element) +} +#end diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/cbor/CborDecodeMapValue.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/cbor/CborDecodeMapValue.vm index 29bd1683e133..c48255d584c0 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/cbor/CborDecodeMapValue.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/cbor/CborDecodeMapValue.vm @@ -1,10 +1,27 @@ +#set($parentMapDepth = $recursionDepth - 1) auto key_${recursionDepth} = decoder->PopNextTextVal(); if (key_${recursionDepth}.has_value()) { Aws::String keyStr_${recursionDepth} = Aws::String(reinterpret_cast(key_${recursionDepth}.value().ptr), key_${recursionDepth}.value().len); +#if($member.shape.sparse) + { + auto nullPeek_${recursionDepth} = decoder->PeekType(); + if (nullPeek_${recursionDepth}.has_value() && nullPeek_${recursionDepth}.value() == Aws::Crt::Cbor::CborType::Null) { + decoder->ConsumeNextSingleElement(); +#if($parentMapDepth == 0) + ${memberVarName}[keyStr_${recursionDepth}]; +#else + nestedMap_${parentMapDepth}[keyStr_${recursionDepth}]; +#end + } else { +#end #if($shapeMember.enum) auto ${containerVar} = decoder->PopNextTextVal(); if (${containerVar}.has_value()) { - ${value}[keyStr_${recursionDepth}] = ${shapeMember.name}Mapper::Get${shapeMember.name}ForName(Aws::String(reinterpret_cast(${containerVar}.value().ptr), ${containerVar}.value().len)); +#if($parentMapDepth == 0) + ${memberVarName}[keyStr_${recursionDepth}] = ${shapeMember.name}Mapper::Get${shapeMember.name}ForName(Aws::String(reinterpret_cast(${containerVar}.value().ptr), ${containerVar}.value().len)); +#else + nestedMap_${parentMapDepth}[keyStr_${recursionDepth}] = ${shapeMember.name}Mapper::Get${shapeMember.name}ForName(Aws::String(reinterpret_cast(${containerVar}.value().ptr), ${containerVar}.value().len)); +#end } #elseif($shapeMember.string) auto peekType_${recursionDepth} = decoder->PeekType(); @@ -12,7 +29,11 @@ if(peekType_${recursionDepth}){ if (peekType_${recursionDepth}.value() == Aws::Crt::Cbor::CborType::Text) { auto ${containerVar} = decoder->PopNextTextVal(); if (${containerVar}.has_value()) { - ${value}[keyStr_${recursionDepth}] = Aws::String(reinterpret_cast(${containerVar}.value().ptr), ${containerVar}.value().len); +#if($parentMapDepth == 0) + ${memberVarName}[keyStr_${recursionDepth}] = Aws::String(reinterpret_cast(${containerVar}.value().ptr), ${containerVar}.value().len); +#else + nestedMap_${parentMapDepth}[keyStr_${recursionDepth}] = Aws::String(reinterpret_cast(${containerVar}.value().ptr), ${containerVar}.value().len); +#end } } else { decoder->ConsumeNextSingleElement(); @@ -30,24 +51,40 @@ if(peekType_${recursionDepth}){ ss_${recursionDepth} << Aws::String(reinterpret_cast(${containerVar}.value().ptr), ${containerVar}.value().len); } } - ${value}[keyStr_${recursionDepth}] = ss_${recursionDepth}.str(); +#if($parentMapDepth == 0) + ${memberVarName}[keyStr_${recursionDepth}] = ss_${recursionDepth}.str(); +#else + nestedMap_${parentMapDepth}[keyStr_${recursionDepth}] = ss_${recursionDepth}.str(); +#end ss_${recursionDepth}.clear(); } } #elseif($shapeMember.boolean) auto ${containerVar} = decoder->PopNextBooleanVal(); if (${containerVar}.has_value()) { - ${value}[keyStr_${recursionDepth}] = ${containerVar}.value(); +#if($parentMapDepth == 0) + ${memberVarName}[keyStr_${recursionDepth}] = ${containerVar}.value(); +#else + nestedMap_${parentMapDepth}[keyStr_${recursionDepth}] = ${containerVar}.value(); +#end } #elseif($shapeMember.double) auto ${containerVar} = decoder->PopNextFloatVal(); if (${containerVar}.has_value()) { - ${value}[keyStr_${recursionDepth}] = ${containerVar}.value(); +#if($parentMapDepth == 0) + ${memberVarName}[keyStr_${recursionDepth}] = ${containerVar}.value(); +#else + nestedMap_${parentMapDepth}[keyStr_${recursionDepth}] = ${containerVar}.value(); +#end } #elseif($shapeMember.float) auto ${containerVar} = decoder->PopNextFloatVal(); if (${containerVar}.has_value()) { - ${value}[keyStr_${recursionDepth}] = ${containerVar}.value(); +#if($parentMapDepth == 0) + ${memberVarName}[keyStr_${recursionDepth}] = ${containerVar}.value(); +#else + nestedMap_${parentMapDepth}[keyStr_${recursionDepth}] = ${containerVar}.value(); +#end } #elseif($shapeMember.blob) auto peekType_${recursionDepth} = decoder->PeekType(); @@ -55,7 +92,11 @@ if(peekType_${recursionDepth}){ if (peekType_${recursionDepth}.value() == Aws::Crt::Cbor::CborType::Bytes) { auto ${containerVar} = decoder->PopNextBytesVal(); if (${containerVar}.has_value()) { - ${value}[keyStr_${recursionDepth}] = Aws::Utils::ByteBuffer(${containerVar}.value().ptr, ${containerVar}.value().len); +#if($parentMapDepth == 0) + ${memberVarName}[keyStr_${recursionDepth}] = Aws::Utils::ByteBuffer(${containerVar}.value().ptr, ${containerVar}.value().len); +#else + nestedMap_${parentMapDepth}[keyStr_${recursionDepth}] = Aws::Utils::ByteBuffer(${containerVar}.value().ptr, ${containerVar}.value().len); +#end } } else { decoder->ConsumeNextSingleElement(); @@ -73,7 +114,11 @@ if(peekType_${recursionDepth}){ ss_${recursionDepth} << Aws::String(reinterpret_cast(${containerVar}.value().ptr), ${containerVar}.value().len); } } - ${value}[keyStr_${recursionDepth}] = Aws::Utils::ByteBuffer(ss_${recursionDepth}.str()); +#if($parentMapDepth == 0) + ${memberVarName}[keyStr_${recursionDepth}] = Aws::Utils::ByteBuffer(ss_${recursionDepth}.str()); +#else + nestedMap_${parentMapDepth}[keyStr_${recursionDepth}] = Aws::Utils::ByteBuffer(ss_${recursionDepth}.str()); +#end ss_${recursionDepth}.clear(); } } @@ -88,23 +133,39 @@ if(peekType_${recursionDepth}){ { auto ${containerVar} = decoder->PopNextFloatVal(); if (${containerVar}.has_value()) { - ${value}[keyStr_${recursionDepth}] = Aws::Utils::DateTime(${containerVar}.value()); +#if($parentMapDepth == 0) + ${memberVarName}[keyStr_${recursionDepth}] = Aws::Utils::DateTime(${containerVar}.value()); +#else + nestedMap_${parentMapDepth}[keyStr_${recursionDepth}] = Aws::Utils::DateTime(${containerVar}.value()); +#end } } else { auto ${containerVar} = decoder->PopNextUnsignedIntVal(); if (${containerVar}.has_value()) { - ${value}[keyStr_${recursionDepth}] = Aws::Utils::DateTime(${containerVar}.value()); +#if($parentMapDepth == 0) + ${memberVarName}[keyStr_${recursionDepth}] = Aws::Utils::DateTime(${containerVar}.value()); +#else + nestedMap_${parentMapDepth}[keyStr_${recursionDepth}] = Aws::Utils::DateTime(${containerVar}.value()); +#end } } } } #elseif($shapeMember.structure) #if($member.shape.isMutuallyReferencedWith($shape) || $member.shape.getName() == $shape.getName()) - ${value}[keyStr_${recursionDepth}] = Aws::MakeShared<${shapeMember.name}>("${typeInfo.className}", ${shapeMember.name}(decoder)); +#if($parentMapDepth == 0) + ${memberVarName}[keyStr_${recursionDepth}] = Aws::MakeShared<${shapeMember.name}>("${typeInfo.className}", ${shapeMember.name}(decoder)); +#else + nestedMap_${parentMapDepth}[keyStr_${recursionDepth}] = Aws::MakeShared<${shapeMember.name}>("${typeInfo.className}", ${shapeMember.name}(decoder)); +#end #else - ${value}[keyStr_${recursionDepth}] = ${shapeMember.name}(decoder); +#if($parentMapDepth == 0) + ${memberVarName}[keyStr_${recursionDepth}] = ${shapeMember.name}(decoder); +#else + nestedMap_${parentMapDepth}[keyStr_${recursionDepth}] = ${shapeMember.name}(decoder); +#end #end #elseif($shapeMember.map) #set($template.nestedShapeMember = $shapeMember.mapValue.shape) @@ -144,9 +205,9 @@ if(peekType_${recursionDepth}){ #set($recursionDepth = $recursionDepth - 1) } } - #if($recursionDepth > 0) + #if($recursionDepth > 1) #set($parentDepth = $recursionDepth - 1) - nestedMap_${parentDepth}[keyStr_${recursionDepth}] = ${value}; + nestedMap_${parentDepth}[keyStr_${recursionDepth}] = nestedMap_${recursionDepth}; #else ${memberVarName}[keyStr_${recursionDepth}] = nestedMap_${recursionDepth}; #end @@ -193,7 +254,7 @@ if(peekType_${recursionDepth}){ } #if($recursionDepth > 1) #set($parentDepth = $recursionDepth - 1) - nestedMap_${parentDepth}[keyStr_${recursionDepth}] = ${value}; + nestedMap_${parentDepth}[keyStr_${recursionDepth}] = nestedList_${recursionDepth}; #else ${memberVarName}[keyStr_${recursionDepth}] = nestedList_${recursionDepth}; #end @@ -204,14 +265,26 @@ if(peekType_${recursionDepth}){ if(peekType_${recursionDepth}.value() == Aws::Crt::Cbor::CborType::UInt){ auto ${containerVar} = decoder->PopNextUnsignedIntVal(); if (${containerVar}.has_value()) { - ${value}[keyStr_${recursionDepth}] = static_cast(${containerVar}.value()); +#if($parentMapDepth == 0) + ${memberVarName}[keyStr_${recursionDepth}] = static_cast(${containerVar}.value()); +#else + nestedMap_${parentMapDepth}[keyStr_${recursionDepth}] = static_cast(${containerVar}.value()); +#end } } else { auto ${containerVar} = decoder->PopNextNegativeIntVal(); if (${containerVar}.has_value()) { - ${value}[keyStr_${recursionDepth}] = static_cast(1 - ${containerVar}.value()); +#if($parentMapDepth == 0) + ${memberVarName}[keyStr_${recursionDepth}] = static_cast(1 - ${containerVar}.value()); +#else + nestedMap_${parentMapDepth}[keyStr_${recursionDepth}] = static_cast(1 - ${containerVar}.value()); +#end } } } #end -} \ No newline at end of file +#if($member.shape.sparse) + } // end else (non-null sparse value) + } +#end +} diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/cbor/CborEncodeValue.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/cbor/CborEncodeValue.vm index 279d4d3dc78f..fd089e19d3d1 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/cbor/CborEncodeValue.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/cbor/CborEncodeValue.vm @@ -3,21 +3,43 @@ encoder.WriteText(Aws::Crt::ByteCursorFromCString(${shapeMember.name}Mapper::Get #elseif($shapeMember.list) encoder.WriteArrayStart(${value}.size()); for(const auto& item_${recursionDepth} : ${value}) { +#if($shapeMember.sparse) + if (!item_${recursionDepth}.has_value()) { encoder.WriteNull(); } else { + const auto& sparseItem_${recursionDepth} = *item_${recursionDepth}; +#set($value = "sparseItem_${recursionDepth}") #set($shapeMember = $shapeMember.listMember.shape) +#set($recursionDepth = $recursionDepth + 1) +#parse("com/amazonaws/util/awsclientgenerator/velocity/cpp/cbor/CborEncodeValue.vm") +#set($recursionDepth = $recursionDepth - 1) + } +#else #set($value = "item_${recursionDepth}") +#set($shapeMember = $shapeMember.listMember.shape) #set($recursionDepth = $recursionDepth + 1) #parse("com/amazonaws/util/awsclientgenerator/velocity/cpp/cbor/CborEncodeValue.vm") #set($recursionDepth = $recursionDepth - 1) +#end } #elseif($shapeMember.map) encoder.WriteMapStart(${value}.size()); for(const auto& item_${recursionDepth} : ${value}) { encoder.WriteText(Aws::Crt::ByteCursorFromCString(item_${recursionDepth}.first.c_str())); +#if($shapeMember.sparse) + if (!item_${recursionDepth}.second.has_value()) { encoder.WriteNull(); } else { + const auto& sparseVal_${recursionDepth} = *item_${recursionDepth}.second; +#set($value = "sparseVal_${recursionDepth}") #set($shapeMember = $shapeMember.mapValue.shape) +#set($recursionDepth = $recursionDepth + 1) +#parse("com/amazonaws/util/awsclientgenerator/velocity/cpp/cbor/CborEncodeValue.vm") +#set($recursionDepth = $recursionDepth - 1) + } +#else #set($value = "item_${recursionDepth}.second") +#set($shapeMember = $shapeMember.mapValue.shape) #set($recursionDepth = $recursionDepth + 1) #parse("com/amazonaws/util/awsclientgenerator/velocity/cpp/cbor/CborEncodeValue.vm") #set($recursionDepth = $recursionDepth - 1) +#end } #elseif($shapeMember.blob) encoder.WriteBytes(Aws::Crt::ByteCursorFromCString(reinterpret_cast(${value}.GetUnderlyingData()))); @@ -40,4 +62,4 @@ encoder.WriteTag(1); //1 represents Epoch-based date/time. See https://www.rfc-e encoder.WriteUInt(${value}.Seconds()); #else (${value} >= 0) ? encoder.WriteUInt(${value}) : encoder.WriteNegInt(${value}); -#end \ No newline at end of file +#end diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/json/ModelInternalMapOrListJsonDeserializer.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/json/ModelInternalMapOrListJsonDeserializer.vm index 492de94d73bc..65d7afff006a 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/json/ModelInternalMapOrListJsonDeserializer.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/json/ModelInternalMapOrListJsonDeserializer.vm @@ -22,6 +22,13 @@ #end ${template.currentSpaces}for(auto& ${template.lowerCaseVarName}Item : ${template.lowerCaseVarName}JsonMap) ${template.currentSpaces}{ +#if($template.currentShape.sparse) + ${template.currentSpaces} if(${template.lowerCaseVarName}Item.second.IsNull()) + ${template.currentSpaces} { + ${template.currentSpaces} ${template.containerVar}[${template.lowerCaseVarName}Item.first]; + ${template.currentSpaces} continue; + ${template.currentSpaces} } +#end #if(!$template.currentShape.mapValue.shape.map && !$template.currentShape.mapValue.shape.list) #set($lvalue = "${template.containerVar}[${template.lowerCaseVarName}Item.first]") #set($rvalue = "${template.lowerCaseVarName}Item.second.As${CppViewHelper.computeJsonCppType($template.currentShape.mapValue.shape)}()") @@ -82,18 +89,41 @@ #end ${template.currentSpaces}for(unsigned ${template.lowerCaseVarName}Index = 0; ${template.lowerCaseVarName}Index < ${template.lowerCaseVarName}JsonList.GetLength(); ++${template.lowerCaseVarName}Index) ${template.currentSpaces}{ +#if($template.currentShape.sparse) + ${template.currentSpaces} if(${template.lowerCaseVarName}JsonList[${template.lowerCaseVarName}Index].IsNull()) + ${template.currentSpaces} { + ${template.currentSpaces} ${template.containerVar}.emplace_back(); + ${template.currentSpaces} continue; + ${template.currentSpaces} } +#end #if(!$template.currentShape.listMember.shape.map && !$template.currentShape.listMember.shape.list) #set($template.atBottom = true) #if($template.currentShape.listMember.shape.enum) #set($enumName = $template.currentShape.listMember.shape.name) +#if($template.currentShape.sparse) + ${template.currentSpaces} ${template.containerVar}.emplace_back(${enumName}Mapper::Get${enumName}ForName(${template.lowerCaseVarName}JsonList[${template.lowerCaseVarName}Index].AsString())); +#else ${template.currentSpaces} ${template.containerVar}.push_back(${enumName}Mapper::Get${enumName}ForName(${template.lowerCaseVarName}JsonList[${template.lowerCaseVarName}Index].AsString())); +#end #elseif($template.currentShape.listMember.shape.blob) +#if($template.currentShape.sparse) + ${template.currentSpaces} ${template.containerVar}.emplace_back(HashingUtils::Base64Decode(${template.lowerCaseVarName}JsonList[${template.lowerCaseVarName}Index].As${CppViewHelper.computeJsonCppType($template.currentShape.listMember.shape)}())); +#else ${template.currentSpaces} ${template.containerVar}.push_back(HashingUtils::Base64Decode(${template.lowerCaseVarName}JsonList[${template.lowerCaseVarName}Index].As${CppViewHelper.computeJsonCppType($template.currentShape.listMember.shape)}())); +#end #elseif($template.currentShape.listMember.shape.timeStamp && $template.currentShape.listMember.shape.timestampFormat == "iso8601") +#if($template.currentShape.sparse) + ${template.currentSpaces} ${template.containerVar}.emplace_back(Aws::Utils::DateTime{${template.lowerCaseVarName}JsonList[${template.lowerCaseVarName}Index].As${CppViewHelper.computeJsonCppType($template.currentShape.listMember.shape)}(), Aws::Utils::DateFormat::$CppViewHelper.computeTimestampFormatInQueryString($template.currentShape.listMember.shape)}); +#else ${template.currentSpaces} ${template.containerVar}.push_back(Aws::Utils::DateTime{${template.lowerCaseVarName}JsonList[${template.lowerCaseVarName}Index].As${CppViewHelper.computeJsonCppType($template.currentShape.listMember.shape)}(), Aws::Utils::DateFormat::$CppViewHelper.computeTimestampFormatInQueryString($template.currentShape.listMember.shape)}); +#end +#else +#if($template.currentShape.sparse) + ${template.currentSpaces} ${template.containerVar}.emplace_back(${template.lowerCaseVarName}JsonList[${template.lowerCaseVarName}Index].As${CppViewHelper.computeJsonCppType($template.currentShape.listMember.shape)}()); #else ${template.currentSpaces} ${template.containerVar}.push_back(${template.lowerCaseVarName}JsonList[${template.lowerCaseVarName}Index].As${CppViewHelper.computeJsonCppType($template.currentShape.listMember.shape)}()); #end +#end #else #set($currentSpaces = $template.currentSpaces + " ") #set($currentShape = $template.currentShape.listMember.shape) diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/json/ModelInternalMapOrListJsonize.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/json/ModelInternalMapOrListJsonize.vm index 56c69280c330..6b102baaae5f 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/json/ModelInternalMapOrListJsonize.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/json/ModelInternalMapOrListJsonize.vm @@ -13,8 +13,31 @@ ${template.currentSpaces}JsonValue ${template.lowerCaseVarName}JsonMap; ${template.currentSpaces}for(auto& ${template.lowerCaseVarName}Item : ${template.containerVar}) ${template.currentSpaces}{ +#if($template.currentShape.sparse) + ${template.currentSpaces} if(!${template.lowerCaseVarName}Item.second.has_value()) + ${template.currentSpaces} { + ${template.currentSpaces} ${template.lowerCaseVarName}JsonMap.WithNull(${template.lowerCaseVarName}Item.first); + ${template.currentSpaces} continue; + ${template.currentSpaces} } +#end #if(!$template.currentShape.mapValue.shape.map && !$template.currentShape.mapValue.shape.list) #set($functionCall = "${template.lowerCaseVarName}JsonMap.With${CppViewHelper.computeJsonCppType($template.currentShape.mapValue.shape)}") +#if($template.currentShape.sparse) +#set($key = "${template.lowerCaseVarName}Item.first") +#set($value = "*${template.lowerCaseVarName}Item.second${CppViewHelper.computeJsonizeString($template.currentShape.mapValue.shape)}") +#if($template.currentShape.mapValue.shape.isBlob()) +#set($value = "HashingUtils::Base64Encode(*${template.lowerCaseVarName}Item.second${CppViewHelper.computeJsonizeString($template.currentShape.mapValue.shape)})") +#end +#if($template.currentShape.mapKey.shape.enum) +#set($enumName = $template.currentShape.mapKey.shape.name) +#set($key = "${enumName}Mapper::GetNameFor${enumName}(${template.lowerCaseVarName}Item.first)") +#end +#if($template.currentShape.mapValue.shape.enum) +#set($enumName = $template.currentShape.mapValue.shape.name) +#set($value = "${enumName}Mapper::GetNameFor${enumName}(*${template.lowerCaseVarName}Item.second)") +#set($functionCall = "${template.lowerCaseVarName}JsonMap.WithString") +#end +#else #set($key = "${template.lowerCaseVarName}Item.first") #set($value = "${template.lowerCaseVarName}Item.second${CppViewHelper.computeJsonizeString($template.currentShape.mapValue.shape)}") #if($template.currentShape.mapValue.shape.isBlob()) @@ -28,6 +51,7 @@ #set($enumName = $template.currentShape.mapValue.shape.name) #set($value = "${enumName}Mapper::GetNameFor${enumName}(${value})") #set($functionCall = "${template.lowerCaseVarName}JsonMap.WithString") +#end #end ${template.currentSpaces} ${functionCall}(${key}, ${value}); #set($template.atBottom = true) @@ -59,16 +83,35 @@ ${template.currentSpaces}${AwsArray} ${template.lowerCaseVarName}JsonList(${template.containerVar}.size()); ${template.currentSpaces}for(unsigned ${template.lowerCaseVarName}Index = 0; ${template.lowerCaseVarName}Index < ${template.lowerCaseVarName}JsonList.GetLength(); ++${template.lowerCaseVarName}Index) ${template.currentSpaces}{ +#if($template.currentShape.sparse) + ${template.currentSpaces} if(!${template.containerVar}[${template.lowerCaseVarName}Index].has_value()) + ${template.currentSpaces} { + ${template.currentSpaces} ${template.lowerCaseVarName}JsonList[${template.lowerCaseVarName}Index].AsNull(); + ${template.currentSpaces} continue; + ${template.currentSpaces} } +#end #if(!$template.currentShape.listMember.shape.map && !$template.currentShape.listMember.shape.list) #set($template.atBottom = true) #if($template.currentShape.listMember.shape.enum) #set($enumName = $template.currentShape.listMember.shape.name) +#if($template.currentShape.sparse) + ${template.currentSpaces} ${template.lowerCaseVarName}JsonList[${template.lowerCaseVarName}Index].AsString(${enumName}Mapper::GetNameFor${enumName}(*${template.containerVar}[${template.lowerCaseVarName}Index])); +#else ${template.currentSpaces} ${template.lowerCaseVarName}JsonList[${template.lowerCaseVarName}Index].AsString(${enumName}Mapper::GetNameFor${enumName}(${template.containerVar}[${template.lowerCaseVarName}Index])); +#end #elseif($template.currentShape.listMember.shape.blob) +#if($template.currentShape.sparse) + ${template.currentSpaces} ${template.lowerCaseVarName}JsonList[${template.lowerCaseVarName}Index].As${CppViewHelper.computeJsonCppType($template.currentShape.listMember.shape)}(HashingUtils::Base64Encode(*${template.containerVar}[${template.lowerCaseVarName}Index]${CppViewHelper.computeJsonizeString($template.currentShape.listMember.shape)})); +#else ${template.currentSpaces} ${template.lowerCaseVarName}JsonList[${template.lowerCaseVarName}Index].As${CppViewHelper.computeJsonCppType($template.currentShape.listMember.shape)}(HashingUtils::Base64Encode(${template.containerVar}[${template.lowerCaseVarName}Index]${CppViewHelper.computeJsonizeString($template.currentShape.listMember.shape)})); +#end +#else +#if($template.currentShape.sparse) + ${template.currentSpaces} ${template.lowerCaseVarName}JsonList[${template.lowerCaseVarName}Index].As${CppViewHelper.computeJsonCppType($template.currentShape.listMember.shape)}(*${template.containerVar}[${template.lowerCaseVarName}Index]${CppViewHelper.computeJsonizeString($template.currentShape.listMember.shape)}); #else ${template.currentSpaces} ${template.lowerCaseVarName}JsonList[${template.lowerCaseVarName}Index].As${CppViewHelper.computeJsonCppType($template.currentShape.listMember.shape)}(${template.containerVar}[${template.lowerCaseVarName}Index]${CppViewHelper.computeJsonizeString($template.currentShape.listMember.shape)}); #end +#end #else #set($currentSpaces = $template.currentSpaces + " ") #set($currentShape = $template.currentShape.listMember.shape) diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/request/SetListMacro.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/request/SetListMacro.vm index 98ee03ac1321..694e9e37e9c2 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/request/SetListMacro.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/request/SetListMacro.vm @@ -31,6 +31,16 @@ ${macro.spaces}{ ${macro.spaces}} #end##foreach #else## not (list || map || structure) +#if($listShape.sparse) +#set($macro.fieldAdder = "Add${CppViewHelper.capitalizeFirstChar($testInputParam.key)}") +#foreach($arrayItem in $testInputParam.value) +#if($arrayItem == "null") +${macro.spaces}${dstObject}.${macro.fieldAdder}(Aws::Crt::Optional<$CppViewHelper.computeCppType($macro.listMemberShape)>{}); +#else +${macro.spaces}${dstObject}.${macro.fieldAdder}(#SerializeSingleParameterMacro($macro.listMemberShape, $arrayItem)); +#end +#end +#else #set($macro.fieldSetter = "Set${CppViewHelper.capitalizeFirstChar($testInputParam.key)}") #set($macro.listResult="{") #foreach($arrayItem in $testInputParam.value) @@ -39,5 +49,6 @@ ${macro.spaces}} #end #set($macro.listResult=$macro.listResult + "}") ${spaces}${dstObject}.${macro.fieldSetter}($macro.listResult); +#end #end##(list || map || structure) #end##macro SetListMacro \ No newline at end of file diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/request/SetMapMacro.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/request/SetMapMacro.vm index 809e27ce2377..bb2656a29b72 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/request/SetMapMacro.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/request/SetMapMacro.vm @@ -29,6 +29,16 @@ ${macro.spaces}} #break #end ###----- the map value is not nested structure or document +#if($mapShape.sparse) +#set($macro.fieldAdder = "Add${CppViewHelper.capitalizeFirstChar($testInputParam.key)}") +#foreach($mapItem in $testInputParam.value.fields()) +#if($mapItem.value == "null") +${macro.spaces}${dstObject}.${macro.fieldAdder}("$mapItem.key", Aws::Crt::Optional<$CppViewHelper.computeCppType($mapShape.mapValue.shape)>{}); +#else +${macro.spaces}${dstObject}.${macro.fieldAdder}("$mapItem.key", #SerializeSingleParameterMacro($mapShape.mapValue.shape, $mapItem.value)); +#end +#end +#else #set($macro.mapResult="{") #foreach($mapItem in $testInputParam.value.fields()) #set($macro.mapItem="{" + '"' + "$mapItem.key" + '"' + ", ") @@ -38,4 +48,5 @@ ${macro.spaces}} #end #set($macro.mapResult=$macro.mapResult + "}") ${spaces}${dstObject}.${macro.fieldSetter}($macro.mapResult); +#end #end##macro SetMapMacro \ No newline at end of file diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/result/ValidateListMacro.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/result/ValidateListMacro.vm index 7c9070a317bd..1dec4b2ea133 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/result/ValidateListMacro.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/result/ValidateListMacro.vm @@ -23,6 +23,23 @@ #set($macro.listItemVarName = "${dstObject}${CppViewHelper.capitalizeFirstChar(${CppViewHelper.computeVariableName($testValidateParam.key)})}Item") #end #if($macro.listMemberShape.list || $macro.listMemberShape.map || $macro.listMemberShape.structure) +#if($listShape.sparse && $macro.listMemberShape.structure) +${macro.spaces}const Aws::Vector>& $macro.listItemVarName = ${dstObject}.${macro.fieldGetter}; +${macro.spaces}EXPECT_EQ(${testValidateParamVal.size()}U, ${macro.listItemVarName}.size()); +#foreach($arrayItem in $testValidateParamVal) +${macro.spaces}{ +#if($arrayItem.isNull()) + ${macro.spaces}EXPECT_FALSE(${macro.listItemVarName}.at(${foreach.index}).has_value()); +#else + ${macro.spaces}EXPECT_TRUE(${macro.listItemVarName}.at(${foreach.index}).has_value()); + ${macro.spaces}const ${macro.listMemberShape.name}& ${macro.listItemVarName}Ref = *${macro.listItemVarName}.at(${foreach.index}); +#foreach($innerParam in $arrayItem.fields()) +#ValidateParamsMacro("${macro.spaces} " "${macro.listItemVarName}Ref" $macro.listMemberShape $innerParam) +#end +#end +${macro.spaces}} +#end +#else ${macro.spaces}EXPECT_EQ(${testValidateParamVal.size()}U, ${dstObject}.${macro.fieldGetter}.size()); #foreach($arrayItem in $testValidateParamVal) ${macro.spaces}{ @@ -47,11 +64,25 @@ ${macro.spaces}{ #end##list ${macro.spaces}} #end##foreach +#end #else## not (list || map || structure) +#if($listShape.sparse) +${macro.spaces}const Aws::Vector>& $macro.listItemVarName = ${dstObject}.${macro.fieldGetter}; +${macro.spaces}EXPECT_EQ(${testValidateParamVal.size()}U, ${macro.listItemVarName}.size()); +#foreach($arrayItem in $testValidateParamVal) +#if($arrayItem.isNull()) +${macro.spaces}EXPECT_FALSE(${macro.listItemVarName}.at(${foreach.index}).has_value()); +#else +${macro.spaces}EXPECT_TRUE(${macro.listItemVarName}.at(${foreach.index}).has_value()); +${macro.spaces}EXPECT_EQ(#ValidateSingleParameterMacro($macro.listMemberShape, $arrayItem), *${macro.listItemVarName}.at(${foreach.index})); +#end +#end +#else ${macro.spaces}const Aws::Vector<$CppViewHelper.computeCppType($macro.listMemberShape)>& $macro.listItemVarName = ${dstObject}.${macro.fieldGetter}; ${macro.spaces}EXPECT_EQ(${testValidateParamVal.size()}U, ${macro.listItemVarName}.size()); #foreach($arrayItem in $testValidateParamVal) ${macro.spaces}EXPECT_EQ(#ValidateSingleParameterMacro($macro.listMemberShape, $arrayItem), ${macro.listItemVarName}.at(${foreach.index})); #end +#end##sparse #end##(list || map || structure) #end##macro ValidateListMacro \ No newline at end of file diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/result/ValidateMapMacro.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/result/ValidateMapMacro.vm index 845748270b70..0bb3482a8fe2 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/result/ValidateMapMacro.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/result/ValidateMapMacro.vm @@ -25,6 +25,24 @@ ${macro.spaces}EXPECT_STREQ(R"j(${mapItem.value})j", ${macro.mapVarName}.at("$ma #break #end #if($mapShape.mapValue.shape.structure) +#if($mapShape.sparse) +${macro.spaces}const Aws::Map<$CppViewHelper.computeCppType($mapShape.mapKey.shape), Aws::Crt::Optional<$CppViewHelper.computeCppType($mapShape.mapValue.shape)>>& $macro.mapVarName = ${dstObject}.${macro.fieldGetter}; +${macro.spaces}EXPECT_EQ(${testValidateParamVal.size()}U, ${macro.mapVarName}.size()); +#foreach($mapItem in $testValidateParamVal.fields()) +${macro.spaces}{ + ${macro.spaces}EXPECT_TRUE(${macro.mapVarName}.find("$mapItem.key") != ${macro.mapVarName}.end()); +#if($mapItem.value.isNull()) + ${macro.spaces}EXPECT_FALSE(${macro.mapVarName}.at("$mapItem.key").has_value()); +#else + ${macro.spaces}EXPECT_TRUE(${macro.mapVarName}.at("$mapItem.key").has_value()); + ${macro.spaces}const $CppViewHelper.computeCppType($mapShape.mapValue.shape)& $macro.mapItemVarName = *${macro.mapVarName}.at("$mapItem.key"); +#foreach($innerParam in $mapItem.value.fields()) +#ValidateParamsMacro("${macro.spaces} " $macro.mapItemVarName $mapShape.mapValue.shape $innerParam) +#end +#end +${macro.spaces}} +#end +#else ${macro.spaces}const Aws::Map<$CppViewHelper.computeCppType($mapShape.mapKey.shape), $CppViewHelper.computeCppType($mapShape.mapValue.shape)>& $macro.mapVarName = ${dstObject}.${macro.fieldGetter}; ${macro.spaces}EXPECT_EQ(${testValidateParamVal.size()}U, ${macro.mapVarName}.size()); #foreach($mapItem in $testValidateParamVal.fields()) @@ -36,9 +54,23 @@ ${macro.spaces}{ #end ${macro.spaces}} #end +#end #break #end ###----- the map value is not nested structure or document +#if($mapShape.sparse) +${macro.spaces}const Aws::Map<$CppViewHelper.computeCppType($mapShape.mapKey.shape), Aws::Crt::Optional<$CppViewHelper.computeCppType($mapShape.mapValue.shape)>>& $macro.mapVarName = ${dstObject}.${macro.fieldGetter}; +${macro.spaces}EXPECT_EQ(${testValidateParamVal.size()}U, ${macro.mapVarName}.size()); +#foreach($mapItem in $testValidateParamVal.fields()) +${macro.spaces}EXPECT_TRUE(${macro.mapVarName}.find("$mapItem.key") != ${macro.mapVarName}.end()); +#if($mapItem.value.isNull()) +${macro.spaces}EXPECT_FALSE(${macro.mapVarName}.at("$mapItem.key").has_value()); +#else +${macro.spaces}EXPECT_TRUE(${macro.mapVarName}.at("$mapItem.key").has_value()); +${macro.spaces}EXPECT_EQ(#ValidateSingleParameterMacro($mapShape.mapValue.shape, $mapItem.value), *${macro.mapVarName}.at("$mapItem.key")); +#end +#end +#else ${macro.spaces}const Aws::Map<$CppViewHelper.computeCppType($mapShape.mapKey.shape), $CppViewHelper.computeCppType($mapShape.mapValue.shape)>& $macro.mapVarName = ${dstObject}.${macro.fieldGetter}; ${macro.spaces}EXPECT_EQ(${testValidateParamVal.size()}U, ${macro.mapVarName}.size()); #foreach($mapItem in $testValidateParamVal.fields()) @@ -48,4 +80,5 @@ ${macro.spaces}EXPECT_TRUE(${macro.mapVarName}.find("$mapItem.key") != ${macro.m #set($macro.var = $macro.mapItemVarName) #ValidateSingleVariableMacro($macro.spaces, $mapShape.mapValue.shape, $mapItem.value, $macro.parentVarName, $macro.getter, $macro.var) #end +#end##sparse #end##macro ValidateMapMacro \ No newline at end of file diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/result/ValidateSingleParameterMacro.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/result/ValidateSingleParameterMacro.vm index 1e5ee6442cd1..d90493ed1b35 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/result/ValidateSingleParameterMacro.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/result/ValidateSingleParameterMacro.vm @@ -38,8 +38,7 @@ Aws::Utils::DateTime(static_cast(${value}))## #elseif($shape.enum) ${shape.name}Mapper::Get${shape.name}ForName(R"e(${value.asText()})e")## #elseif($shape.list) -#set($macro.listResult="Aws::Vector<$CppViewHelper.computeCppType($shape)>({") -#foreach($listItem in $value) +#set($macro.listResult="Aws::Vector<$CppViewHelper.computeCppType($shape.listMember.shape)>({")#foreach($listItem in $value) #set($macro.listResult=$macro.listResult + "#ValidateSingleParameterMacro($shape.listMember.shape, $listItem)") #if($foreach.hasNext)#set($macro.listResult=$macro.listResult + ", ")#end #end diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/queryxml/QuerySerializeTemplateMacros/serializeRequestQueryListElement.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/queryxml/QuerySerializeTemplateMacros/serializeRequestQueryListElement.vm index 03c8ca9e6bab..f4e686065506 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/queryxml/QuerySerializeTemplateMacros/serializeRequestQueryListElement.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/queryxml/QuerySerializeTemplateMacros/serializeRequestQueryListElement.vm @@ -45,10 +45,23 @@ #end #end #if($member.shape.listMember.shape.structure) +#if($member.shape.sparse) + ${macro.spaces} if(item.has_value()) { + ${macro.spaces} item.value().OutputToStream(ss, "${macro.listLocation}.", ${varName}Count, ""); + ${macro.spaces} } +#else ${macro.spaces} item.OutputToStream(ss, "${macro.listLocation}.", ${varName}Count, ""); +#end +#else +#if($member.shape.sparse) + ${macro.spaces} if(item.has_value()) { + ${macro.spaces} ss << "${macro.listLocation}." << ${varName}Count << "=" + ${macro.spaces} << #serializeQuerySingleElementToText($macro.spaces, $member.shape.listMember, "item.value()") << "&"; + ${macro.spaces} } #else ${macro.spaces} ss << "${macro.listLocation}." << ${varName}Count << "=" ${macro.spaces} << #serializeQuerySingleElementToText($macro.spaces, $member.shape.listMember, "item") << "&"; +#end #end ${macro.spaces} ${varName}Count++; ${macro.spaces}} diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/queryxml/QuerySerializeTemplateMacros/serializeRequestQueryMapElement.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/queryxml/QuerySerializeTemplateMacros/serializeRequestQueryMapElement.vm index 751eca7c55ab..f797d4abb67a 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/queryxml/QuerySerializeTemplateMacros/serializeRequestQueryMapElement.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/queryxml/QuerySerializeTemplateMacros/serializeRequestQueryMapElement.vm @@ -35,14 +35,27 @@ #end ## --- MAP VALUE --- #if($member.shape.mapValue.shape.structure) +#if($member.shape.sparse) + ${spaces} if(item.second.has_value()) { + ${spaces} item.second.value().OutputToStream(ss, "${macro.mapLocationName}.", ${macro.varName}Count, ".${macro.valueLocationName}"); + ${spaces} } +#else ${spaces} item.second.OutputToStream(ss, "${macro.mapLocationName}.", ${macro.varName}Count, ".${macro.valueLocationName}"); +#end #else #set($macro.equals='=') #if($member.shape.mapValue.shape.list || $member.shape.mapValue.shape.map) #set($macro.equals='') #end +#if($member.shape.sparse) + ${spaces} if(item.second.has_value()) { + ${spaces} ss << "${macro.mapLocationName}." << ${macro.varName}Count << ".${macro.valueLocationName}${macro.equals}" + ${spaces} << #serializeQuerySingleElementToText($spaces, $member.shape.mapValue, "item.second.value()") << "&"; + ${spaces} } +#else ${spaces} ss << "${macro.mapLocationName}." << ${macro.varName}Count << ".${macro.valueLocationName}${macro.equals}" ${spaces} << #serializeQuerySingleElementToText($spaces, $member.shape.mapValue, "item.second") << "&"; +#end #end ${spaces} ${macro.varName}Count++; ${spaces}} diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/queryxml/QuerySerializeTemplateMacros/serializeSubObjQueryMapElement.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/queryxml/QuerySerializeTemplateMacros/serializeSubObjQueryMapElement.vm index 633eddb064d3..4db390fc41b7 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/queryxml/QuerySerializeTemplateMacros/serializeSubObjQueryMapElement.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/queryxml/QuerySerializeTemplateMacros/serializeSubObjQueryMapElement.vm @@ -32,14 +32,26 @@ #if($member.shape.mapValue.shape.structure) ${spaces} Aws::StringStream ${macro.lowerCaseVarName}Ss; ${spaces} ${macro.lowerCaseVarName}Ss << location << ${macro.locationIndexValue}".${macro.mapLocationName}." << ${macro.lowerCaseVarName}Idx << ".${macro.mapValueLocationName}"; +#if($member.shape.sparse) + ${spaces} if(item.second.has_value()) { + ${spaces} item.second.value().OutputToStream(oStream, ${macro.lowerCaseVarName}Ss.str().c_str()); + ${spaces} } +#else ${spaces} item.second.OutputToStream(oStream, ${macro.lowerCaseVarName}Ss.str().c_str()); +#end #else #set($macro.equals='="') #if($member.shape.mapValue.shape.list || $member.shape.mapValue.shape.map) #set($macro.equals='"') #end #set($mapValueLocation = '".' + "${macro.mapLocationName}." + '"' + " << ${macro.lowerCaseVarName}Idx << " + '".' + ${macro.mapValueLocationName} + $macro.equals + $nl + " ${spaces} ") +#if($member.shape.sparse) + ${spaces} if(item.second.has_value()) { + ${spaces} oStream << location << ${macro.locationIndexValue}#serializeSubObjQuerySingleElement($member.shape.mapValue, $mapValueLocation, "item.second.value()") << "&"; + ${spaces} } +#else ${spaces} oStream << location << ${macro.locationIndexValue}#serializeSubObjQuerySingleElement($member.shape.mapValue, $mapValueLocation, "item.second") << "&"; +#end #end ${spaces} ${macro.lowerCaseVarName}Idx++; ${spaces}} diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlDeserializeTemplateMacros/deserializeXmlListPayloadElement.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlDeserializeTemplateMacros/deserializeXmlListPayloadElement.vm index 289c96de1220..be8e43a22dbf 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlDeserializeTemplateMacros/deserializeXmlListPayloadElement.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlDeserializeTemplateMacros/deserializeXmlListPayloadElement.vm @@ -54,7 +54,19 @@ ${macro.spaces}while(!${macro.listVarName}.IsNull()) ${macro.spaces}{ #set($macro.memberVarName = $CppViewHelper.computeMemberVariableName($memberName)) +#if($member.shape.sparse) + ${macro.spaces} if(${macro.listVarName}.GetText().empty() || ${macro.listVarName}.GetAttributeValue("xsi:nil") == "true") { + ${macro.spaces} ${macro.memberVarName}.emplace_back(); + ${macro.spaces} } else { +#if($member.shape.listMember.shape.structure) + ${macro.spaces} ${macro.memberVarName}.emplace_back(#deserializeXmlSingleElement($member.shape.listMember, $macro.listVarName)); +#else + ${macro.spaces} ${macro.memberVarName}.push_back(#deserializeXmlSingleElement($member.shape.listMember, $macro.listVarName)); +#end + ${macro.spaces} } +#else ${macro.spaces} ${macro.memberVarName}.push_back(#deserializeXmlSingleElement($member.shape.listMember, $macro.listVarName)); +#end #if($member.shape.listMember.locationName) #set($listMemberName = $member.shape.listMember.locationName) #elseif(!($member.shape.flattened || $member.flattened)) diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlDeserializeTemplateMacros/deserializeXmlMapPayloadElement.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlDeserializeTemplateMacros/deserializeXmlMapPayloadElement.vm index c117ed91570a..1c3ed3ccc637 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlDeserializeTemplateMacros/deserializeXmlMapPayloadElement.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlDeserializeTemplateMacros/deserializeXmlMapPayloadElement.vm @@ -38,8 +38,14 @@ ${macro.spaces} XmlNode valueNode = ${macro.mapVarName}.FirstChild("value"); #end #set($macro.memberVarName = $CppViewHelper.computeMemberVariableName($memberName)) +#if($member.shape.sparse) + ${macro.spaces} if(valueNode.IsNull() || valueNode.GetAttributeValue("xsi:nil") == "true") { ${macro.memberVarName}[#deserializeXmlSingleElement($member.shape.mapKey, "keyNode")]; } else { + ${macro.spaces} ${macro.memberVarName}[#deserializeXmlSingleElement($member.shape.mapKey, "keyNode")] = + ${macro.spaces} #deserializeXmlSingleElement($member.shape.mapValue, "valueNode", $macro.spaces, false); } +#else ${macro.spaces} ${macro.memberVarName}[#deserializeXmlSingleElement($member.shape.mapKey, "keyNode")] = ${macro.spaces} #deserializeXmlSingleElement($member.shape.mapValue, "valueNode", $macro.spaces, false); +#end #if($member.locationName) ${macro.spaces} ${macro.mapVarName} = ${macro.mapVarName}.NextNode("${member.locationName}"); #else diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlDeserializeTemplateMacros/deserializeXmlNestedListElement.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlDeserializeTemplateMacros/deserializeXmlNestedListElement.vm index f04e717dbbb3..015c9b215b24 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlDeserializeTemplateMacros/deserializeXmlNestedListElement.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlDeserializeTemplateMacros/deserializeXmlNestedListElement.vm @@ -8,7 +8,15 @@ ${macro.spaces} if(${memberVarName}.IsNull()) { return ${macro.resultVarName}; } ${macro.spaces} XmlNode ${macro.resultVarName}MemberNode = ${memberVarName}.FirstChild("${CppViewHelper.ifNotNullOrEmpty($member.locationName, 'member')}"); ${macro.spaces} while(!${macro.resultVarName}MemberNode.IsNull()) { +#if($member.shape.sparse) + ${macro.spaces} if(${macro.resultVarName}MemberNode.IsNull() || ${macro.resultVarName}MemberNode.GetText().empty()) { + ${macro.spaces} ${macro.resultVarName}.push_back(Aws::Crt::Optional<$CppViewHelper.computeCppType($member.shape.listMember.shape)>{}); + ${macro.spaces} } else { + ${macro.spaces} ${macro.resultVarName}.push_back(#deserializeXmlSingleElement($member.shape.listMember, "${macro.resultVarName}MemberNode")); + ${macro.spaces} } +#else ${macro.spaces} ${macro.resultVarName}.push_back(#deserializeXmlSingleElement($member.shape.listMember, "${macro.resultVarName}MemberNode")); +#end ${macro.spaces} ${macro.resultVarName}MemberNode = ${macro.resultVarName}MemberNode.NextNode("${CppViewHelper.ifNotNullOrEmpty($member.locationName, 'member')}"); ${macro.spaces} } ${macro.spaces} return ${macro.resultVarName}; diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlDeserializeTemplateMacros/deserializeXmlNestedMapElement.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlDeserializeTemplateMacros/deserializeXmlNestedMapElement.vm index 2eadbc20f8ec..52ee6eeb9c25 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlDeserializeTemplateMacros/deserializeXmlNestedMapElement.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlDeserializeTemplateMacros/deserializeXmlNestedMapElement.vm @@ -23,8 +23,17 @@ ${macro.spaces} while(!${macro.resultVarName}EntryNode.IsNull()) { ${macro.spaces} XmlNode ${macro.resultVarName}KeyNode = ${macro.resultVarName}EntryNode.FirstChild("${CppViewHelper.ifNotNullOrEmpty($member.shape.mapKey.locationName, 'key')}"); ${macro.spaces} XmlNode ${macro.resultVarName}ValNode = ${macro.resultVarName}EntryNode.FirstChild("${CppViewHelper.ifNotNullOrEmpty($member.shape.mapValue.locationName, 'value')}"); +#if($member.shape.sparse) + ${macro.spaces} if(${macro.resultVarName}ValNode.IsNull() || ${macro.resultVarName}ValNode.GetText().empty()) { + ${macro.spaces} ${macro.resultVarName}[#deserializeXmlSingleElement($member.shape.mapKey, "${macro.resultVarName}KeyNode")] = Aws::Crt::Optional<$CppViewHelper.computeCppType($member.shape.mapValue.shape)>{}; + ${macro.spaces} } else { + ${macro.spaces} ${macro.resultVarName}[#deserializeXmlSingleElement($member.shape.mapKey, "${macro.resultVarName}KeyNode")] = + ${macro.spaces} #deserializeXmlSingleElement($member.shape.mapValue, "${macro.resultVarName}ValNode", $macro.spaces, false); + ${macro.spaces} } +#else ${macro.spaces} ${macro.resultVarName}[#deserializeXmlSingleElement($member.shape.mapKey, "${macro.resultVarName}KeyNode")] = ${macro.spaces} #deserializeXmlSingleElement($member.shape.mapValue, "${macro.resultVarName}ValNode", $macro.spaces, false); +#end ${macro.spaces} ${macro.resultVarName}EntryNode = ${macro.resultVarName}EntryNode.NextNode("${CppViewHelper.ifNotNullOrEmpty($member.locationName, 'entry')}"); ${macro.spaces} } ${macro.spaces} return ${macro.resultVarName}; diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlSerializeTemplateMacros/serializeXmlListPayloadElement.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlSerializeTemplateMacros/serializeXmlListPayloadElement.vm index cacc0d8899a9..a046ef956287 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlSerializeTemplateMacros/serializeXmlListPayloadElement.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlSerializeTemplateMacros/serializeXmlListPayloadElement.vm @@ -29,6 +29,15 @@ ## if list is flattened than the name of repeated XML element is ShapeMember name in parent name OR explicitly set by parent's locationName #set($macro.listMemberSerializationName = ${CppViewHelper.ifNotNullOrEmpty($member.locationName, $serializationName)}) #end +#if($member.shape.sparse) + ${spaces} if(!${macro.listItemVarName}.has_value()) { + ${spaces} XmlNode ${lowerCaseVarName}NilNode = ${macro.listMemberParentNode}.CreateChildElement("${macro.listMemberSerializationName}"); + ${spaces} ${lowerCaseVarName}NilNode.SetAttributeValue("xsi:nil", "true"); + ${spaces} } else { +#serializeXmlSinglePayloadElement($macro.listSpaces, $macro.listMemberSerializationName, $lowerCaseVarName, $member.shape.listMember, "(*${macro.listItemVarName})", $macro.listMemberParentNode) + ${spaces} } +#else #serializeXmlSinglePayloadElement($macro.listSpaces, $macro.listMemberSerializationName, $lowerCaseVarName, $member.shape.listMember, $macro.listItemVarName, $macro.listMemberParentNode) +#end ${spaces}} #end##macro serializeXmlListPayloadElement \ No newline at end of file diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlSerializeTemplateMacros/serializeXmlMapPayloadElement.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlSerializeTemplateMacros/serializeXmlMapPayloadElement.vm index abd754414e4a..23fa939fe361 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlSerializeTemplateMacros/serializeXmlMapPayloadElement.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/xml/XmlSerializeTemplateMacros/serializeXmlMapPayloadElement.vm @@ -25,6 +25,15 @@ #set($macro.mapKeySerializationName = "#if($member.shape.mapKey.locationName)$member.shape.mapKey.locationName#{else}key#end") #serializeXmlSinglePayloadElement($macro.mapSpaces, $macro.mapKeySerializationName, "${lowerCaseVarName}Key", $member.shape.mapKey, "${macro.mapItemVarName}.first", "${lowerCaseVarName}MapEntryNode") #set($macro.mapValueSerializationName = "#if($member.shape.mapValue.locationName)$member.shape.mapValue.locationName#{else}value#end") +#if($member.shape.sparse) + ${spaces} if(!${macro.mapItemVarName}.second.has_value()) { + ${spaces} XmlNode ${lowerCaseVarName}NilNode = ${lowerCaseVarName}MapEntryNode.CreateChildElement("${macro.mapValueSerializationName}"); + ${spaces} ${lowerCaseVarName}NilNode.SetAttributeValue("xsi:nil", "true"); + ${spaces} } else { +#serializeXmlSinglePayloadElement($macro.mapSpaces, $macro.mapValueSerializationName, "${lowerCaseVarName}Value", $member.shape.mapValue, "(*${macro.mapItemVarName}.second)", "${lowerCaseVarName}MapEntryNode") + ${spaces} } +#else #serializeXmlSinglePayloadElement($macro.mapSpaces, $macro.mapValueSerializationName, "${lowerCaseVarName}Value", $member.shape.mapValue, "${macro.mapItemVarName}.second", "${lowerCaseVarName}MapEntryNode") +#end ${spaces}} #end##macro serializeXmlMapPayloadElement \ No newline at end of file diff --git a/tools/scripts/run_code_generation.py b/tools/scripts/run_code_generation.py index 29b8e9986389..a90bd4422459 100644 --- a/tools/scripts/run_code_generation.py +++ b/tools/scripts/run_code_generation.py @@ -156,7 +156,10 @@ def main(): return -1 if args["generate_protocol_tests"]: - protocol_tests_generator = ProtocolTestsGen(args) + # Disable smithy generation for protocol tests + protocol_args = args.copy() + protocol_args["disable_smithy_generation"] = True + protocol_tests_generator = ProtocolTestsGen(protocol_args) if protocol_tests_generator.generate(executor, max_workers) != 0: print("ERROR: Failed to generate protocol test(s)!") return -1