Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ProtocolTests] Refactor XML serialization codegen template, #3277

Merged
merged 4 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace EC2Protocol
{
namespace Model
{
class RecursiveXmlShapesOutputNested2;

class RecursiveXmlShapesOutputNested1
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace EC2Protocol
{
namespace Model
{
class RecursiveXmlShapesOutputNested1;

class RecursiveXmlShapesOutputNested2
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ XmlTimestampsResponse& XmlTimestampsResponse::operator =(const Aws::AmazonWebSer
XmlNode epochSecondsNode = resultNode.FirstChild("epochSeconds");
if(!epochSecondsNode.IsNull())
{
m_epochSeconds = DateTime(StringUtils::Trim(Aws::Utils::Xml::DecodeEscapedXmlText(epochSecondsNode.GetText()).c_str()).c_str(), Aws::Utils::DateFormat::$CppViewHelper.computeTimestampFormatInXml($member.shape));
m_epochSeconds = DateTime(StringUtils::ConvertToDouble(StringUtils::Trim(Aws::Utils::Xml::DecodeEscapedXmlText(epochSecondsNode.GetText()).c_str()).c_str()));
}
XmlNode epochSecondsOnTargetNode = resultNode.FirstChild("epochSecondsOnTarget");
if(!epochSecondsOnTargetNode.IsNull())
{
m_epochSecondsOnTarget = DateTime(StringUtils::Trim(Aws::Utils::Xml::DecodeEscapedXmlText(epochSecondsOnTargetNode.GetText()).c_str()).c_str(), Aws::Utils::DateFormat::$CppViewHelper.computeTimestampFormatInXml($member.shape));
m_epochSecondsOnTarget = DateTime(StringUtils::ConvertToDouble(StringUtils::Trim(Aws::Utils::Xml::DecodeEscapedXmlText(epochSecondsOnTargetNode.GetText()).c_str()).c_str()));
}
XmlNode httpDateNode = resultNode.FirstChild("httpDate");
if(!httpDateNode.IsNull())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace QueryProtocol
{
namespace Model
{
class RecursiveXmlShapesOutputNested2;

class RecursiveXmlShapesOutputNested1
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace QueryProtocol
{
namespace Model
{
class RecursiveXmlShapesOutputNested1;

class RecursiveXmlShapesOutputNested2
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ XmlTimestampsResult& XmlTimestampsResult::operator =(const Aws::AmazonWebService
XmlNode epochSecondsNode = resultNode.FirstChild("epochSeconds");
if(!epochSecondsNode.IsNull())
{
m_epochSeconds = DateTime(StringUtils::Trim(Aws::Utils::Xml::DecodeEscapedXmlText(epochSecondsNode.GetText()).c_str()).c_str(), Aws::Utils::DateFormat::$CppViewHelper.computeTimestampFormatInXml($member.shape));
m_epochSeconds = DateTime(StringUtils::ConvertToDouble(StringUtils::Trim(Aws::Utils::Xml::DecodeEscapedXmlText(epochSecondsNode.GetText()).c_str()).c_str()));
}
XmlNode epochSecondsOnTargetNode = resultNode.FirstChild("epochSecondsOnTarget");
if(!epochSecondsOnTargetNode.IsNull())
{
m_epochSecondsOnTarget = DateTime(StringUtils::Trim(Aws::Utils::Xml::DecodeEscapedXmlText(epochSecondsOnTargetNode.GetText()).c_str()).c_str(), Aws::Utils::DateFormat::$CppViewHelper.computeTimestampFormatInXml($member.shape));
m_epochSecondsOnTarget = DateTime(StringUtils::ConvertToDouble(StringUtils::Trim(Aws::Utils::Xml::DecodeEscapedXmlText(epochSecondsOnTargetNode.GetText()).c_str()).c_str()));
}
XmlNode httpDateNode = resultNode.FirstChild("httpDate");
if(!httpDateNode.IsNull())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace RestXmlProtocol
{
namespace Model
{
class RecursiveShapesInputOutputNested2;

class RecursiveShapesInputOutputNested1
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace RestXmlProtocol
{
namespace Model
{
class RecursiveShapesInputOutputNested1;

class RecursiveShapesInputOutputNested2
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ Aws::String FlattenedXmlMapRequest::SerializePayload() const
Aws::StringStream ss;
if(m_myMapHasBeenSet)
{
XmlNode myMapParentNode = parentNode.CreateChildElement("myMap");
for(const auto& mapItem : m_myMap)
{
XmlNode myMapMapEntryNode = myMapParentNode.CreateChildElement("entry");
XmlNode myMapKeyNode = myMapMapEntryNode.CreateChildElement("key");
myMapKeyNode.SetText(mapItem.first);
XmlNode myMapValueNode = myMapMapEntryNode.CreateChildElement("value");
myMapValueNode.SetText(FooEnumMapper::GetNameForFooEnum(mapItem.second));
}
}

return payloadDoc.ConvertToString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ Aws::String FlattenedXmlMapWithXmlNameRequest::SerializePayload() const
Aws::StringStream ss;
if(m_myMapHasBeenSet)
{
XmlNode myMapParentNode = parentNode.CreateChildElement("KVP");
for(const auto& mapItem : m_myMap)
{
XmlNode myMapMapEntryNode = myMapParentNode.CreateChildElement("KVP");
XmlNode myMapKeyNode = myMapMapEntryNode.CreateChildElement("K");
myMapKeyNode.SetText(mapItem.first);
XmlNode myMapValueNode = myMapMapEntryNode.CreateChildElement("V");
myMapValueNode.SetText(mapItem.second);
}
}

return payloadDoc.ConvertToString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ Aws::String NestedXmlMapWithXmlNameRequest::SerializePayload() const
Aws::StringStream ss;
if(m_nestedXmlMapWithXmlNameMapHasBeenSet)
{
XmlNode nestedXmlMapWithXmlNameMapParentNode = parentNode.CreateChildElement("nestedXmlMapWithXmlNameMap");
for(const auto& mapItem : m_nestedXmlMapWithXmlNameMap)
{
XmlNode nestedXmlMapWithXmlNameMapMapEntryNode = nestedXmlMapWithXmlNameMapParentNode.CreateChildElement("entry");
XmlNode nestedXmlMapWithXmlNameMapKeyNode = nestedXmlMapWithXmlNameMapMapEntryNode.CreateChildElement("OuterKey");
nestedXmlMapWithXmlNameMapKeyNode.SetText(mapItem.first);
XmlNode nestedXmlMapWithXmlNameMapValueNode = nestedXmlMapWithXmlNameMapMapEntryNode.CreateChildElement("value");
nestedXmlMapWithXmlNameMapValueNode.SetText(mapItem.second);
}
}

return payloadDoc.ConvertToString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,28 @@ Aws::String NestedXmlMapsRequest::SerializePayload() const
Aws::StringStream ss;
if(m_nestedMapHasBeenSet)
{
XmlNode nestedMapParentNode = parentNode.CreateChildElement("nestedMap");
for(const auto& mapItem : m_nestedMap)
{
XmlNode nestedMapMapEntryNode = nestedMapParentNode.CreateChildElement("entry");
XmlNode nestedMapKeyNode = nestedMapMapEntryNode.CreateChildElement("key");
nestedMapKeyNode.SetText(mapItem.first);
XmlNode nestedMapValueNode = nestedMapMapEntryNode.CreateChildElement("value");
nestedMapValueNode.SetText(mapItem.second);
}
}

if(m_flatNestedMapHasBeenSet)
{
XmlNode flatNestedMapParentNode = parentNode.CreateChildElement("flatNestedMap");
for(const auto& mapItem : m_flatNestedMap)
{
XmlNode flatNestedMapMapEntryNode = flatNestedMapParentNode.CreateChildElement("entry");
XmlNode flatNestedMapKeyNode = flatNestedMapMapEntryNode.CreateChildElement("key");
flatNestedMapKeyNode.SetText(mapItem.first);
XmlNode flatNestedMapValueNode = flatNestedMapMapEntryNode.CreateChildElement("value");
flatNestedMapValueNode.SetText(mapItem.second);
}
}

return payloadDoc.ConvertToString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Aws::String XmlEmptyListsRequest::SerializePayload() const
for(const auto& item : m_timestampList)
{
XmlNode timestampListNode = timestampListParentNode.CreateChildElement("Timestamp");
timestampListNode.SetText(item.ToGmtString(Aws::Utils::DateFormat::ISO_8601);
timestampListNode.SetText(item.ToGmtString(Aws::Utils::DateFormat::ISO_8601));
}
}

Expand Down Expand Up @@ -122,6 +122,7 @@ Aws::String XmlEmptyListsRequest::SerializePayload() const
for(const auto& item : m_nestedStringList)
{
XmlNode nestedStringListNode = nestedStringListParentNode.CreateChildElement("StringList");
nestedStringListNode.SetText(item);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ Aws::String XmlEmptyMapsRequest::SerializePayload() const
Aws::StringStream ss;
if(m_myMapHasBeenSet)
{
XmlNode myMapParentNode = parentNode.CreateChildElement("myMap");
for(const auto& mapItem : m_myMap)
{
XmlNode myMapMapEntryNode = myMapParentNode.CreateChildElement("entry");
XmlNode myMapKeyNode = myMapMapEntryNode.CreateChildElement("key");
myMapKeyNode.SetText(mapItem.first);
XmlNode myMapValueNode = myMapMapEntryNode.CreateChildElement("value");
mapItem.second.AddToNode(myMapValueNode);
}
}

return payloadDoc.ConvertToString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ Aws::String XmlEnumsRequest::SerializePayload() const

if(m_fooEnumMapHasBeenSet)
{
XmlNode fooEnumMapParentNode = parentNode.CreateChildElement("fooEnumMap");
for(const auto& mapItem : m_fooEnumMap)
{
XmlNode fooEnumMapMapEntryNode = fooEnumMapParentNode.CreateChildElement("entry");
XmlNode fooEnumMapKeyNode = fooEnumMapMapEntryNode.CreateChildElement("key");
fooEnumMapKeyNode.SetText(mapItem.first);
XmlNode fooEnumMapValueNode = fooEnumMapMapEntryNode.CreateChildElement("value");
fooEnumMapValueNode.SetText(FooEnumMapper::GetNameForFooEnum(mapItem.second));
}
}

return payloadDoc.ConvertToString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,17 @@ Aws::String XmlIntEnumsRequest::SerializePayload() const

if(m_intEnumMapHasBeenSet)
{
XmlNode intEnumMapParentNode = parentNode.CreateChildElement("intEnumMap");
for(const auto& mapItem : m_intEnumMap)
{
XmlNode intEnumMapMapEntryNode = intEnumMapParentNode.CreateChildElement("entry");
XmlNode intEnumMapKeyNode = intEnumMapMapEntryNode.CreateChildElement("key");
intEnumMapKeyNode.SetText(mapItem.first);
XmlNode intEnumMapValueNode = intEnumMapMapEntryNode.CreateChildElement("value");
ss << mapItem.second;
intEnumMapValueNode.SetText(ss.str());
ss.str("");
}
}

return payloadDoc.ConvertToString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Aws::String XmlListsRequest::SerializePayload() const
for(const auto& item : m_timestampList)
{
XmlNode timestampListNode = timestampListParentNode.CreateChildElement("Timestamp");
timestampListNode.SetText(item.ToGmtString(Aws::Utils::DateFormat::ISO_8601);
timestampListNode.SetText(item.ToGmtString(Aws::Utils::DateFormat::ISO_8601));
}
}

Expand Down Expand Up @@ -122,6 +122,7 @@ Aws::String XmlListsRequest::SerializePayload() const
for(const auto& item : m_nestedStringList)
{
XmlNode nestedStringListNode = nestedStringListParentNode.CreateChildElement("StringList");
nestedStringListNode.SetText(item);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ Aws::String XmlMapWithXmlNamespaceRequest::SerializePayload() const
Aws::StringStream ss;
if(m_myMapHasBeenSet)
{
XmlNode myMapParentNode = parentNode.CreateChildElement("KVP");
for(const auto& mapItem : m_myMap)
{
XmlNode myMapMapEntryNode = myMapParentNode.CreateChildElement("KVP");
XmlNode myMapKeyNode = myMapMapEntryNode.CreateChildElement("K");
myMapKeyNode.SetText(mapItem.first);
XmlNode myMapValueNode = myMapMapEntryNode.CreateChildElement("V");
myMapValueNode.SetText(mapItem.second);
}
}

return payloadDoc.ConvertToString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ Aws::String XmlMapsRequest::SerializePayload() const
Aws::StringStream ss;
if(m_myMapHasBeenSet)
{
XmlNode myMapParentNode = parentNode.CreateChildElement("myMap");
for(const auto& mapItem : m_myMap)
{
XmlNode myMapMapEntryNode = myMapParentNode.CreateChildElement("entry");
XmlNode myMapKeyNode = myMapMapEntryNode.CreateChildElement("key");
myMapKeyNode.SetText(mapItem.first);
XmlNode myMapValueNode = myMapMapEntryNode.CreateChildElement("value");
mapItem.second.AddToNode(myMapValueNode);
}
}

return payloadDoc.ConvertToString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ Aws::String XmlMapsXmlNameRequest::SerializePayload() const
Aws::StringStream ss;
if(m_myMapHasBeenSet)
{
XmlNode myMapParentNode = parentNode.CreateChildElement("myMap");
for(const auto& mapItem : m_myMap)
{
XmlNode myMapMapEntryNode = myMapParentNode.CreateChildElement("entry");
XmlNode myMapKeyNode = myMapMapEntryNode.CreateChildElement("Attribute");
myMapKeyNode.SetText(mapItem.first);
XmlNode myMapValueNode = myMapMapEntryNode.CreateChildElement("Setting");
mapItem.second.AddToNode(myMapValueNode);
}
}

return payloadDoc.ConvertToString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,25 +53,25 @@ Aws::String XmlTimestampsRequest::SerializePayload() const
if(m_epochSecondsHasBeenSet)
{
XmlNode epochSecondsNode = parentNode.CreateChildElement("epochSeconds");
epochSecondsNode.SetText(m_epochSeconds.ToGmtString(Aws::Utils::DateFormat::ISO_8601));
epochSecondsNode.SetText(StringUtils::to_string(m_epochSeconds.Seconds()));
}

if(m_epochSecondsOnTargetHasBeenSet)
{
XmlNode epochSecondsOnTargetNode = parentNode.CreateChildElement("epochSecondsOnTarget");
epochSecondsOnTargetNode.SetText(m_epochSecondsOnTarget.ToGmtString(Aws::Utils::DateFormat::ISO_8601));
epochSecondsOnTargetNode.SetText(StringUtils::to_string(m_epochSecondsOnTarget.Seconds()));
}

if(m_httpDateHasBeenSet)
{
XmlNode httpDateNode = parentNode.CreateChildElement("httpDate");
httpDateNode.SetText(m_httpDate.ToGmtString(Aws::Utils::DateFormat::ISO_8601));
httpDateNode.SetText(m_httpDate.ToGmtString(Aws::Utils::DateFormat::RFC822));
}

if(m_httpDateOnTargetHasBeenSet)
{
XmlNode httpDateOnTargetNode = parentNode.CreateChildElement("httpDateOnTarget");
httpDateOnTargetNode.SetText(m_httpDateOnTarget.ToGmtString(Aws::Utils::DateFormat::ISO_8601));
httpDateOnTargetNode.SetText(m_httpDateOnTarget.ToGmtString(Aws::Utils::DateFormat::RFC822));
}

return payloadDoc.ConvertToString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ XmlTimestampsResult& XmlTimestampsResult::operator =(const Aws::AmazonWebService
XmlNode epochSecondsNode = resultNode.FirstChild("epochSeconds");
if(!epochSecondsNode.IsNull())
{
m_epochSeconds = DateTime(StringUtils::Trim(Aws::Utils::Xml::DecodeEscapedXmlText(epochSecondsNode.GetText()).c_str()).c_str(), Aws::Utils::DateFormat::$CppViewHelper.computeTimestampFormatInXml($member.shape));
m_epochSeconds = DateTime(StringUtils::ConvertToDouble(StringUtils::Trim(Aws::Utils::Xml::DecodeEscapedXmlText(epochSecondsNode.GetText()).c_str()).c_str()));
}
XmlNode epochSecondsOnTargetNode = resultNode.FirstChild("epochSecondsOnTarget");
if(!epochSecondsOnTargetNode.IsNull())
{
m_epochSecondsOnTarget = DateTime(StringUtils::Trim(Aws::Utils::Xml::DecodeEscapedXmlText(epochSecondsOnTargetNode.GetText()).c_str()).c_str(), Aws::Utils::DateFormat::$CppViewHelper.computeTimestampFormatInXml($member.shape));
m_epochSecondsOnTarget = DateTime(StringUtils::ConvertToDouble(StringUtils::Trim(Aws::Utils::Xml::DecodeEscapedXmlText(epochSecondsOnTargetNode.GetText()).c_str()).c_str()));
}
XmlNode httpDateNode = resultNode.FirstChild("httpDate");
if(!httpDateNode.IsNull())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void ObjectIdentifier::AddToNode(XmlNode& parentNode) const
if(m_lastModifiedTimeHasBeenSet)
{
XmlNode lastModifiedTimeNode = parentNode.CreateChildElement("LastModifiedTime");
lastModifiedTimeNode.SetText(m_lastModifiedTime.ToGmtString(Aws::Utils::DateFormat::ISO_8601));
lastModifiedTimeNode.SetText(m_lastModifiedTime.ToGmtString(Aws::Utils::DateFormat::RFC822));
}

if(m_sizeHasBeenSet)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void ObjectIdentifier::AddToNode(XmlNode& parentNode) const
if(m_lastModifiedTimeHasBeenSet)
{
XmlNode lastModifiedTimeNode = parentNode.CreateChildElement("LastModifiedTime");
lastModifiedTimeNode.SetText(m_lastModifiedTime.ToGmtString(Aws::Utils::DateFormat::ISO_8601));
lastModifiedTimeNode.SetText(m_lastModifiedTime.ToGmtString(Aws::Utils::DateFormat::RFC822));
}

if(m_sizeHasBeenSet)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,15 @@ void LambdaInvokeOperation::AddToNode(XmlNode& parentNode) const

if(m_userArgumentsHasBeenSet)
{
XmlNode userArgumentsParentNode = parentNode.CreateChildElement("UserArguments");
for(const auto& mapItem : m_userArguments)
{
XmlNode userArgumentsMapEntryNode = userArgumentsParentNode.CreateChildElement("entry");
XmlNode userArgumentsKeyNode = userArgumentsMapEntryNode.CreateChildElement("key");
userArgumentsKeyNode.SetText(mapItem.first);
XmlNode userArgumentsValueNode = userArgumentsMapEntryNode.CreateChildElement("value");
userArgumentsValueNode.SetText(mapItem.second);
}
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,15 @@ void S3ObjectMetadata::AddToNode(XmlNode& parentNode) const

if(m_userMetadataHasBeenSet)
{
XmlNode userMetadataParentNode = parentNode.CreateChildElement("UserMetadata");
for(const auto& mapItem : m_userMetadata)
{
XmlNode userMetadataMapEntryNode = userMetadataParentNode.CreateChildElement("entry");
XmlNode userMetadataKeyNode = userMetadataMapEntryNode.CreateChildElement("key");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if possible can it be simplified into
userMetadataMapEntryNode.CreateChildElement("key").SetText(mapItem.first)
and
userMetadataMapEntryNode.CreateChildElement("value").SetText(mapItem.first)
from the codegen?
i.e. can we support chaining for the setters at a node level for all its immediate children?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One way I have dealt with this in the past is from java (using recursive function and a context) to generate the code and then just use the code in the template. This will greatly simplify the velocity template and push the computation on the Java side

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both key and value types can be other than Strings,

please refer to a generated example:

   XmlNode intEnumMapParentNode = parentNode.CreateChildElement("intEnumMap");
   for(const auto& mapItem : m_intEnumMap)
   {
     XmlNode intEnumMapMapEntryNode = intEnumMapParentNode.CreateChildElement("entry");
     XmlNode intEnumMapKeyNode = intEnumMapMapEntryNode.CreateChildElement("key");
     intEnumMapKeyNode.SetText(mapItem.first);
     XmlNode intEnumMapValueNode = intEnumMapMapEntryNode.CreateChildElement("value");
     ss << mapItem.second;
     intEnumMapValueNode.SetText(ss.str());
     ss.str("");
   }

the current approach is to create a parent element following the model, then create key/value elements following the same model.
The macro serializing the each individual element does not care about if we are within Map or List, it just knows the current item to be serialized under the current parent.
Trying to optimize the appearance of generated code will make the codegen even harder.

Move to generating the code to .java is also quite debatable.
It may appear to be easier on a first glance, but on a fresh look, the complexity looks equal. The .vm allows to match the generated output to the template, while the simple streaming of new code into the buffer using any programming language does not.

The current goal is to make SDK compliant with protocol tests.
Refactoring and optimizations of generated models will follow later.

userMetadataKeyNode.SetText(mapItem.first);
XmlNode userMetadataValueNode = userMetadataMapEntryNode.CreateChildElement("value");
userMetadataValueNode.SetText(mapItem.second);
}
}

if(m_contentLengthHasBeenSet)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ namespace ${serviceNamespace}
{
namespace Model
{
#foreach($forwardDeclaration in $typeInfo.forwardDeclarations)
class $forwardDeclaration;
#end
#set($xmlRef = "${typeInfo.xmlNodeType}&")
#set($classNameRef = "${typeInfo.className}&")

Expand Down
Loading