You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2022/02/24 12:46:55 UTC
[plc4x] branch feature/cleaned-up-type-references updated: feat(codegen): Fixed array type handling and data-io code generation
This is an automated email from the ASF dual-hosted git repository.
cdutz pushed a commit to branch feature/cleaned-up-type-references
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/feature/cleaned-up-type-references by this push:
new 7c59bc3 feat(codegen): Fixed array type handling and data-io code generation
7c59bc3 is described below
commit 7c59bc310776f4ffc7e4e55e04134f9de0311463
Author: cdutz <ch...@c-ware.de>
AuthorDate: Thu Feb 24 13:46:42 2022 +0100
feat(codegen): Fixed array type handling and data-io code generation
---
.../language/java/JavaLanguageTemplateHelper.java | 14 +++++
.../templates/java/data-io-template.java.ftlh | 2 +-
.../templates/java/enum-template.java.ftlh | 33 ++++++++++--
.../templates/java/model-template.java.ftlh | 59 ++++++++++------------
.../mspec/model/fields/DefaultArrayField.java | 15 ++++++
.../model/fields/DefaultManualArrayField.java | 15 ++++++
.../references/DefaultArrayTypeReference.java | 38 ++++++++++++++
.../mspec/parser/MessageFormatListener.java | 14 +++--
.../src/main/resources/protocols/test/test.mspec | 8 +--
pom.xml | 2 +-
10 files changed, 155 insertions(+), 45 deletions(-)
diff --git a/code-generation/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java b/code-generation/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
index 206964b..c9ec4a2 100644
--- a/code-generation/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
+++ b/code-generation/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
@@ -91,6 +91,14 @@ public class JavaLanguageTemplateHelper extends BaseFreemarkerLanguageTemplateHe
public String getLanguageTypeNameForTypeReference(TypeReference typeReference, boolean allowPrimitive) {
Objects.requireNonNull(typeReference);
+ if (typeReference instanceof ArrayTypeReference) {
+ final ArrayTypeReference arrayTypeReference = (ArrayTypeReference) typeReference;
+ if(arrayTypeReference.getElementTypeReference().isByteBased()) {
+ return getLanguageTypeNameForTypeReference(arrayTypeReference.getElementTypeReference()) + "[]";
+ } else {
+ return "List<" + getLanguageTypeNameForTypeReference(arrayTypeReference.getElementTypeReference()) + ">";
+ }
+ }
if (!(typeReference instanceof SimpleTypeReference)) {
return ((NonSimpleTypeReference) typeReference).getName();
}
@@ -360,6 +368,9 @@ public class JavaLanguageTemplateHelper extends BaseFreemarkerLanguageTemplateHe
final String languageTypeName = getLanguageTypeNameForTypeReference(typeReference);
final SimpleTypeReference enumBaseTypeReference = getEnumBaseTypeReference(typeReference);
return "new DataReaderEnumDefault<>(" + languageTypeName + "::" + resolverMethod + ", " + getDataReaderCall(enumBaseTypeReference) + ")";
+ } else if (typeReference.isArrayTypeReference()) {
+ final ArrayTypeReference arrayTypeReference = typeReference.asArrayTypeReference().orElseThrow();
+ return getDataReaderCall(arrayTypeReference.getElementTypeReference(), resolverMethod);
} else if (typeReference.isSimpleTypeReference()) {
SimpleTypeReference simpleTypeReference = typeReference.asSimpleTypeReference().orElseThrow(IllegalStateException::new);
return getDataReaderCall(simpleTypeReference);
@@ -431,6 +442,9 @@ public class JavaLanguageTemplateHelper extends BaseFreemarkerLanguageTemplateHe
if (typeReference.isSimpleTypeReference()) {
SimpleTypeReference simpleTypeReference = typeReference.asSimpleTypeReference().orElseThrow(IllegalStateException::new);
return getDataWriterCall(simpleTypeReference);
+ } else if (typeReference.isArrayTypeReference()) {
+ final ArrayTypeReference arrayTypeReference = typeReference.asArrayTypeReference().orElseThrow();
+ return getDataWriterCall(arrayTypeReference.getElementTypeReference(), fieldName);
} else if (typeReference.isComplexTypeReference()) {
return "new DataWriterComplexDefault<>(writeBuffer)";
} else {
diff --git a/code-generation/language-java/src/main/resources/templates/java/data-io-template.java.ftlh b/code-generation/language-java/src/main/resources/templates/java/data-io-template.java.ftlh
index 39e1639..1be65b3 100644
--- a/code-generation/language-java/src/main/resources/templates/java/data-io-template.java.ftlh
+++ b/code-generation/language-java/src/main/resources/templates/java/data-io-template.java.ftlh
@@ -150,7 +150,7 @@ public class ${type.name} {
<#-- A terminated array keeps on reading data as long as the termination expression evaluates to false -->
<#elseif arrayField.isTerminatedArrayField()>
// Terminated array
- List<${helper.getNonPrimitiveLanguageTypeNameForField(arrayField)}> ${arrayField.name} = new LinkedList<>();
+ ${helper.getNonPrimitiveLanguageTypeNameForField(arrayField)} ${arrayField.name} = new LinkedList<>();
while(!((boolean) (${helper.toParseExpression(arrayField, helper.boolTypeReference, arrayField.loopExpression,parserArguments)}))) {
${arrayField.name}.add(<#if arrayField.type.isSimpleTypeReference()>${helper.getReadBufferReadMethodCall(arrayField.type.asSimpleTypeReference().orElseThrow(), "", arrayField)}<#else>${arrayField.type.asComplexTypeReference().orElseThrow().name}IO.staticParse(readBuffer<#if arrayField.params.isPresent()>, <#list arrayField.params.orElseThrow() as parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(arrayField.type, parserArgument?index), tru [...]
diff --git a/code-generation/language-java/src/main/resources/templates/java/enum-template.java.ftlh b/code-generation/language-java/src/main/resources/templates/java/enum-template.java.ftlh
index 4bf9207..d7822c2 100644
--- a/code-generation/language-java/src/main/resources/templates/java/enum-template.java.ftlh
+++ b/code-generation/language-java/src/main/resources/templates/java/enum-template.java.ftlh
@@ -60,9 +60,36 @@ import java.util.Map;
public enum ${type.name} {
-<#list type.enumValues as enumValue>
- ${enumValue.name}(<#if type.type.isPresent()>(${helper.getLanguageTypeNameForTypeReference(type.type.orElseThrow(), true)}) <#if type.type.orElseThrow().isComplexTypeReference()><#if helper.isEnumTypeReference(type.type.orElseThrow())>${helper.getLanguageTypeNameForTypeReference(type.type.orElseThrow(), true)}.${enumValue.value}<#else>${enumValue.value}</#if><#else>${enumValue.value}</#if></#if><#if type.constantNames?has_content><#if type.type?has_content>, </#if><#list type.constan [...]
-</#sep></#list>;
+<@compress single_line=true>
+ <#list type.enumValues as enumValue>
+ ${enumValue.name}(
+ <#if type.type.isPresent()>
+ (${helper.getLanguageTypeNameForTypeReference(type.type.orElseThrow(), true)})
+ <#if type.type.orElseThrow().isNonSimpleTypeReference()>
+ <#if type.type.orElseThrow().isEnumTypeReference()>
+ ${helper.getLanguageTypeNameForTypeReference(type.type.orElseThrow(), true)}.${enumValue.value}
+ <#else>
+ ${enumValue.value}
+ </#if>
+ <#else>
+ ${enumValue.value}
+ </#if>
+ </#if>
+ <#if type.constantNames?has_content>
+ <#if type.type?has_content>, </#if>
+ <#list type.constantNames as constantName>
+ <#if type.getConstantType(constantName).isNonSimpleTypeReference()>
+ <#if helper.escapeValue(type.getConstantType(constantName), enumValue.getConstant(constantName).orElse(null)) == 'null'>
+ null
+ <#elseif type.getConstantType(constantName).isEnumTypeReference()>
+ ${helper.getLanguageTypeNameForTypeReference(type.getConstantType(constantName), true)}.${helper.escapeValue(type.getConstantType(constantName), enumValue.getConstant(constantName).orElseThrow())}<#else>(${helper.getLanguageTypeNameForTypeReference(type.getConstantType(constantName), true)}) ${helper.escapeValue(type.getConstantType(constantName), enumValue.getConstant(constantName).orElseThrow())}</#if><#else>(${helper.getLanguageTypeNameForTypeReference(type [...]
+ </#if>
+ <#sep>, </#sep>
+ </#list>
+ </#if>)
+ <#sep>, </#sep>
+ </#list>;
+</...@compress>
<#if type.type.isPresent()>
private static final Logger logger = LoggerFactory.getLogger(${type.name}.class);
diff --git a/code-generation/language-java/src/main/resources/templates/java/model-template.java.ftlh b/code-generation/language-java/src/main/resources/templates/java/model-template.java.ftlh
index 8e28069..6d3a1c0 100644
--- a/code-generation/language-java/src/main/resources/templates/java/model-template.java.ftlh
+++ b/code-generation/language-java/src/main/resources/templates/java/model-template.java.ftlh
@@ -123,7 +123,7 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
// Properties.
<#list type.propertyFields as field>
- protected final <#if field.loopType?? && field.type.isByteBased()>byte[]<#elseif field.loopType??>List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}><#else>${helper.getLanguageTypeNameForField(field)}</#if> ${field.name};
+ protected final ${helper.getLanguageTypeNameForField(field)} ${field.name};
</#list>
</#if>
<#if parserArguments?has_content>
@@ -141,14 +141,7 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
<@compress single_line=true>
public ${type.name}(
<#list type.getAllPropertyFields() as field>
- <#if field.loopType?? && field.type.isByteBased()>
- byte[]
- <#elseif field.loopType??>
- List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}>
- <#else>
- ${helper.getLanguageTypeNameForField(field)}
- </#if>
- ${field.name}
+ ${helper.getLanguageTypeNameForField(field)} ${field.name}
<#sep>, </#sep>
</#list>
<#if filteredParserArguments?has_content>
@@ -193,18 +186,18 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
}
<#list type.abstractFields as field>
- public abstract <#if field.loopType?? && field.type.isByteBased()>byte[]<#elseif field.loopType??>List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}><#else>${helper.getLanguageTypeNameForField(field)}</#if> get${field.asNamedField().orElseThrow().name?cap_first}();
+ public abstract ${helper.getLanguageTypeNameForField(field)} get${field.asNamedField().orElseThrow().name?cap_first}();
</#list>
<#list type.propertyFields as field>
- public <#if field.loopType?? && field.type.isByteBased()>byte[]<#elseif field.loopType??>List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}><#else>${helper.getLanguageTypeNameForField(field)}</#if> get${field.name?cap_first}() {
+ public ${helper.getLanguageTypeNameForField(field)} get${field.name?cap_first}() {
return ${field.name};
}
</#list>
<#list type.virtualFields as field>
<#if !type.isDiscriminatorField(field.name)>
- public <#if field.loopType?? && field.type.isByteBased()>byte[]<#elseif field.loopType??>List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}><#else>${helper.getLanguageTypeNameForField(field)}</#if> get${field.name?cap_first}() {
+ public ${helper.getLanguageTypeNameForField(field)} get${field.name?cap_first}() {
<#if helper.getLanguageTypeNameForField(field) = 'String'>
return ${helper.getLanguageTypeNameForField(field)}.valueOf(${helper.toSerializationExpression(field, field.type, field.valueExpression, parserArguments)});
<#elseif helper.getLanguageTypeNameForField(field) = 'BigInteger'>
@@ -241,10 +234,10 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
<#assign namedField = field.asNamedField().orElseThrow()>
// Array Field (${arrayField.name})
- <#if arrayField.type.isByteBased()>
+ <#if arrayField.type.elementTypeReference.isByteBased()>
writeByteArrayField("${namedField.name}", ${namedField.name}, writeByteArray(writeBuffer, 8));
- <#elseif arrayField.type.isSimpleTypeReference()>
- writeSimpleTypeArrayField("${namedField.name}", ${namedField.name}, ${helper.getDataWriterCall(typedField.type, namedField.name)});
+ <#elseif arrayField.type.elementTypeReference.isSimpleTypeReference()>
+ writeSimpleTypeArrayField("${namedField.name}", ${namedField.name}, ${helper.getDataWriterCall(arrayField.type.elementTypeReference, namedField.name)});
<#else>
writeComplexTypeArrayField("${namedField.name}", ${namedField.name}, writeBuffer);
</#if>
@@ -297,7 +290,7 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
<#assign namedField = field.asNamedField().orElseThrow()>
// Manual Array Field (${manualArrayField.name})
- writeManualArrayField("${namedField.name}", ${namedField.name}, (${helper.getNonPrimitiveLanguageTypeNameForField(typedField)} _value) -> ${helper.toParseExpression(manualArrayField, manualArrayField.type, manualArrayField.serializeExpression, parserArguments)}, writeBuffer);
+ writeManualArrayField("${namedField.name}", ${namedField.name}, (${helper.getNonPrimitiveLanguageTypeNameForField(typedField)} _value) -> ${helper.toParseExpression(manualArrayField, manualArrayField.type.elementTypeReference, manualArrayField.serializeExpression, parserArguments)}, writeBuffer);
<#break>
<#case "manual">
<#assign manualField = field.asManualField().orElseThrow()>
@@ -384,16 +377,17 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
<#switch field.typeName>
<#case "array">
<#assign arrayField = field.asArrayField().orElseThrow()>
+ <#assign arrayElementTypeReference = arrayField.type.asArrayTypeReference().orElseThrow().getElementTypeReference()>
// Array field
if(${arrayField.name} != null) {
- <#if arrayField.type.isSimpleTypeReference()>
- <#assign simpleTypeReference = arrayField.type.asSimpleTypeReference().orElseThrow()>
- lengthInBits += ${simpleTypeReference.sizeInBits} * ${arrayField.name}.<#if arrayField.type.isByteBased()>length<#else>size()</#if>;
+ <#if arrayElementTypeReference.isSimpleTypeReference()>
+ <#assign simpleTypeReference = arrayElementTypeReference.asSimpleTypeReference().orElseThrow()>
+ lengthInBits += ${simpleTypeReference.sizeInBits} * ${arrayField.name}.<#if arrayElementTypeReference.isByteBased()>length<#else>size()</#if>;
<#elseif arrayField.isCountArrayField()>
int i=0;
- <#assign complexTypeReference = arrayField.type.asComplexTypeReference().orElseThrow()>
- for(${complexTypeReference.name} element : ${arrayField.name}) {
+ <#assign nonSimpleTypeReference = arrayElementTypeReference.asNonSimpleTypeReference().orElseThrow()>
+ for(${nonSimpleTypeReference.name} element : ${arrayField.name}) {
boolean last = ++i >= ${arrayField.name}.size();
lengthInBits += element.getLengthInBits();
}
@@ -457,6 +451,7 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
<#break>
<#case "manualArray">
<#assign manualArrayField = field.asManualArrayField().orElseThrow()>
+ <#assign arrayElementTypeReference = manualArrayField.type.asArrayTypeReference().orElseThrow().getElementTypeReference()>
// Manual Array Field (${manualArrayField.name})
lengthInBits += ${helper.toParseExpression(manualArrayField, helper.intTypeReference, manualArrayField.lengthExpression, parserArguments)} * 8;
@@ -587,8 +582,9 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
<#assign arrayField = field.asArrayField().orElseThrow()>
<#assign typedField = field.asTypedField().orElseThrow()>
<#assign namedField = field.asNamedField().orElseThrow()>
+ <#assign arrayElementTypeReference = arrayField.type.asArrayTypeReference().orElseThrow().getElementTypeReference()>
- <#if typedField.type.isByteBased()>
+ <#if arrayElementTypeReference.isByteBased()>
<#if !field.isCountArrayField() && !field.isLengthArrayField()>
throw new ParseException("array fields of type byte only support 'count' and 'length' loop-types.");
</#if>
@@ -596,15 +592,15 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
<#else>
<#-- If this is a count array, we can directly initialize an array with the given size -->
<#if field.isCountArrayField()>
- List<${helper.getNonPrimitiveLanguageTypeNameForField(arrayField)}> ${arrayField.name} = readCountArrayField("${arrayField.name}", ${helper.getDataReaderCall(arrayField.type)}, ${helper.toParseExpression(arrayField, helper.intTypeReference, arrayField.loopExpression, parserArguments)}${helper.getFieldOptions(typedField, parserArguments)});
+ ${helper.getNonPrimitiveLanguageTypeNameForField(arrayField)} ${arrayField.name} = readCountArrayField("${arrayField.name}", ${helper.getDataReaderCall(arrayField.type)}, ${helper.toParseExpression(arrayField, helper.intTypeReference, arrayField.loopExpression, parserArguments)}${helper.getFieldOptions(typedField, parserArguments)});
<#-- In all other cases do we have to work with a list, that is later converted to an array -->
<#else>
<#-- For a length array, we read data till the read position of the buffer reaches a given position -->
<#if field.isLengthArrayField()>
- List<${helper.getNonPrimitiveLanguageTypeNameForField(arrayField)}> ${arrayField.name} = readLengthArrayField("${arrayField.name}", ${helper.getDataReaderCall(arrayField.type)}, ${helper.toParseExpression(arrayField, helper.intTypeReference, arrayField.loopExpression, parserArguments)}${helper.getFieldOptions(typedField, parserArguments)});
+ ${helper.getNonPrimitiveLanguageTypeNameForField(arrayField)} ${arrayField.name} = readLengthArrayField("${arrayField.name}", ${helper.getDataReaderCall(arrayField.type)}, ${helper.toParseExpression(arrayField, helper.intTypeReference, arrayField.loopExpression, parserArguments)}${helper.getFieldOptions(typedField, parserArguments)});
<#-- A terminated array keeps on reading data as long as the termination expression evaluates to false -->
<#elseif field.isTerminatedArrayField()>
- List<${helper.getNonPrimitiveLanguageTypeNameForField(arrayField)}> ${arrayField.name} = readTerminatedArrayField("${arrayField.name}", ${helper.getDataReaderCall(arrayField.type)}, () -> ((boolean) (${helper.toParseExpression(arrayField, helper.intTypeReference, arrayField.loopExpression, parserArguments)}))${helper.getFieldOptions(typedField, parserArguments)});
+ ${helper.getNonPrimitiveLanguageTypeNameForField(arrayField)} ${arrayField.name} = readTerminatedArrayField("${arrayField.name}", ${helper.getDataReaderCall(arrayField.type)}, () -> ((boolean) (${helper.toParseExpression(arrayField, helper.intTypeReference, arrayField.loopExpression, parserArguments)}))${helper.getFieldOptions(typedField, parserArguments)});
</#if>
</#if>
</#if>
@@ -655,11 +651,12 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
<#assign manualArrayField = field.asManualArrayField().orElseThrow()>
<#assign typedField = field.asTypedField().orElseThrow()>
<#assign namedField = field.asNamedField().orElseThrow()>
+ <#assign arrayElementTypeReference = manualArrayField.type.asArrayTypeReference().orElseThrow().getElementTypeReference()>
- <#if manualArrayField.type.isByteBased()>
+ <#if arrayElementTypeReference.isByteBased()>
byte[] ${namedField.name} = readManualByteArrayField("${namedField.name}", readBuffer, (byte[] _values) -> (boolean) (${helper.toParseExpression(manualArrayField, helper.boolTypeReference, manualArrayField.loopExpression, parserArguments)}), () -> (${helper.getLanguageTypeNameForField(manualArrayField)}) (${helper.toParseExpression(manualArrayField, manualArrayField.type, manualArrayField.parseExpression, parserArguments)})${helper.getFieldOptions(typedField, parserAr [...]
<#else>
- List<${helper.getNonPrimitiveLanguageTypeNameForField(manualArrayField)}> ${namedField.name} = readManualArrayField("${namedField.name}", readBuffer, (List<${helper.getNonPrimitiveLanguageTypeNameForField(manualArrayField)}> _values) -> (boolean) (${helper.toParseExpression(manualArrayField, helper.boolTypeReference, manualArrayField.loopExpression, parserArguments)}), () -> (${helper.getLanguageTypeNameForField(manualArrayField)}) (${helper.toParseExpression(manualAr [...]
+ ${helper.getNonPrimitiveLanguageTypeNameForField(manualArrayField)} ${namedField.name} = readManualArrayField("${namedField.name}", readBuffer, (${helper.getNonPrimitiveLanguageTypeNameForField(manualArrayField)} _values) -> (boolean) (${helper.toParseExpression(manualArrayField, helper.boolTypeReference, manualArrayField.loopExpression, parserArguments)}), () -> (${helper.getLanguageTypeNameForField(manualArrayField)}) (${helper.toParseExpression(manualArrayField, ma [...]
</#if>
<#break>
<#case "manual">
@@ -778,7 +775,7 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
<#if type.isDiscriminatedParentTypeDefinition()>
public static interface ${type.name}Builder {
- ${type.name} build(<#list type.propertyFields as field><#if field.loopType??>List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}><#else>${helper.getLanguageTypeNameForField(field)}</#if> ${field.name}<#sep>, </#sep></#list><#if filteredParserArguments?has_content><#if type.propertyFields?has_content>, </#if><#list filteredParserArguments as arg>${helper.getLanguageTypeNameForTypeReference(arg.type)} ${arg.name}<#sep>, </#sep></#list></#if>);
+ ${type.name} build(<#list type.propertyFields as field>${helper.getLanguageTypeNameForField(field)} ${field.name}<#sep>, </#sep></#list><#if filteredParserArguments?has_content><#if type.propertyFields?has_content>, </#if><#list filteredParserArguments as arg>${helper.getLanguageTypeNameForTypeReference(arg.type)} ${arg.name}<#sep>, </#sep></#list></#if>);
}
</#if>
@@ -786,7 +783,7 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
public static class ${type.name}Builder implements ${type.parentType.orElseThrow().name}.${type.parentType.orElseThrow().name}Builder {
<#if type.propertyFields?has_content>
<#list type.propertyFields as field>
- private final <#if field.loopType?? && field.type.isByteBased()>byte[]<#elseif field.loopType??>List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}><#else>${helper.getLanguageTypeNameForField(field)}</#if> ${field.name};
+ private final ${helper.getLanguageTypeNameForField(field)} ${field.name};
</#list>
</#if>
<#if filteredParserArguments?has_content>
@@ -795,7 +792,7 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
</#list>
</#if>
- public ${type.name}Builder(<#list type.propertyFields as field><#if field.loopType?? && field.type.isByteBased()>byte[]<#elseif field.loopType??>List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}><#else>${helper.getLanguageTypeNameForField(field)}</#if> ${field.name}<#sep>, </#sep></#list><#if filteredParserArguments?has_content><#if type.propertyFields?has_content>, </#if><#list filteredParserArguments as arg>${helper.getLanguageTypeNameForTypeReference(arg.type)} ${a [...]
+ public ${type.name}Builder(<#list type.propertyFields as field>${helper.getLanguageTypeNameForField(field)} ${field.name}<#sep>, </#sep></#list><#if filteredParserArguments?has_content><#if type.propertyFields?has_content>, </#if><#list filteredParserArguments as arg>${helper.getLanguageTypeNameForTypeReference(arg.type)} ${arg.name}<#sep>, </#sep></#list></#if>) {
<#list type.propertyFields as field>
this.${field.name} = ${field.name};
</#list>
@@ -806,7 +803,7 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
</#if>
}
- public ${type.name} build(<#list type.parentType.orElseThrow().asComplexTypeDefinition().orElseThrow().propertyFields as field><#if field.loopType?? && field.type.isByteBased()>byte[]<#elseif field.loopType??>List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}><#else>${helper.getLanguageTypeNameForField(field)}</#if> ${field.name}<#sep>, </#sep></#list><#if filteredParentParserArguments?has_content><#if type.parentType.orElseThrow().asComplexTypeDefinition().orElseThrow [...]
+ public ${type.name} build(<#list type.parentType.orElseThrow().asComplexTypeDefinition().orElseThrow().propertyFields as field>${helper.getLanguageTypeNameForField(field)} ${field.name}<#sep>, </#sep></#list><#if filteredParentParserArguments?has_content><#if type.parentType.orElseThrow().asComplexTypeDefinition().orElseThrow().propertyFields?has_content>, </#if><#list filteredParentParserArguments as arg>${helper.getLanguageTypeNameForTypeReference(arg.type)} ${arg.name}<#sep>, [...]
return new ${type.name}(<#list type.allPropertyFields as field>${field.name}<#sep>, </#sep></#list><#if filteredParserArguments?has_content><#if type.allPropertyFields?has_content>, </#if><#list filteredParserArguments as arg>${arg.name}<#sep>, </#sep></#list></#if>);
}
}
diff --git a/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/fields/DefaultArrayField.java b/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/fields/DefaultArrayField.java
index 8468f82..36a615d 100644
--- a/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/fields/DefaultArrayField.java
+++ b/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/fields/DefaultArrayField.java
@@ -19,6 +19,8 @@
package org.apache.plc4x.plugins.codegenerator.language.mspec.model.fields;
import org.apache.plc4x.plugins.codegenerator.types.fields.ArrayField;
+import org.apache.plc4x.plugins.codegenerator.types.references.ArrayTypeReference;
+import org.apache.plc4x.plugins.codegenerator.types.references.TypeReference;
import org.apache.plc4x.plugins.codegenerator.types.terms.Term;
import java.util.Map;
@@ -44,6 +46,19 @@ public class DefaultArrayField extends DefaultTypedNamedField implements ArrayFi
}
@Override
+ public void setType(TypeReference typeReference) {
+ if(!(typeReference instanceof ArrayTypeReference)) {
+ throw new IllegalArgumentException("Array fields can only have ArrayTypeReferences");
+ }
+ super.setType(typeReference);
+ }
+
+ @Override
+ public ArrayTypeReference getType() {
+ return (ArrayTypeReference) super.getType();
+ }
+
+ @Override
public String toString() {
return "DefaultArrayField{" +
"loopType=" + loopType +
diff --git a/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/fields/DefaultManualArrayField.java b/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/fields/DefaultManualArrayField.java
index 9678161..60de76e 100644
--- a/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/fields/DefaultManualArrayField.java
+++ b/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/fields/DefaultManualArrayField.java
@@ -19,6 +19,8 @@
package org.apache.plc4x.plugins.codegenerator.language.mspec.model.fields;
import org.apache.plc4x.plugins.codegenerator.types.fields.ManualArrayField;
+import org.apache.plc4x.plugins.codegenerator.types.references.ArrayTypeReference;
+import org.apache.plc4x.plugins.codegenerator.types.references.TypeReference;
import org.apache.plc4x.plugins.codegenerator.types.terms.Term;
import java.util.Map;
@@ -62,6 +64,19 @@ public class DefaultManualArrayField extends DefaultTypedNamedField implements M
}
@Override
+ public void setType(TypeReference typeReference) {
+ if(!(typeReference instanceof ArrayTypeReference)) {
+ throw new IllegalArgumentException("Manual array fields can only have ArrayTypeReferences");
+ }
+ super.setType(typeReference);
+ }
+
+ @Override
+ public ArrayTypeReference getType() {
+ return (ArrayTypeReference) super.getType();
+ }
+
+ @Override
public String toString() {
return "DefaultManualArrayField{" +
"loopType=" + loopType +
diff --git a/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/references/DefaultArrayTypeReference.java b/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/references/DefaultArrayTypeReference.java
new file mode 100644
index 0000000..c639e2b
--- /dev/null
+++ b/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/references/DefaultArrayTypeReference.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.plc4x.plugins.codegenerator.language.mspec.model.references;
+
+import org.apache.plc4x.plugins.codegenerator.types.definitions.TypeDefinition;
+import org.apache.plc4x.plugins.codegenerator.types.references.ArrayTypeReference;
+import org.apache.plc4x.plugins.codegenerator.types.references.TypeReference;
+
+public class DefaultArrayTypeReference implements ArrayTypeReference {
+
+ final TypeReference elementTypeReference;
+
+ public DefaultArrayTypeReference(TypeReference elementTypeReference) {
+ this.elementTypeReference = elementTypeReference;
+ }
+
+ @Override
+ public TypeReference getElementTypeReference() {
+ return elementTypeReference;
+ }
+
+}
diff --git a/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java b/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
index b7bdafc..177add9 100644
--- a/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
+++ b/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
@@ -212,7 +212,7 @@ public class MessageFormatListener extends MSpecBaseListener implements LazyType
LOGGER.error("Error setting type for {}", field, throwable);
return;
}
- field.setType(typeReference);
+ field.setType(new DefaultArrayTypeReference(typeReference));
});
if (parserContexts.peek() != null) {
parserContexts.peek().add(field);
@@ -330,7 +330,7 @@ public class MessageFormatListener extends MSpecBaseListener implements LazyType
LOGGER.error("Error setting type for {}", field, throwable);
return;
}
- field.setType(typeReference);
+ field.setType(new DefaultArrayTypeReference(typeReference));
});
if (parserContexts.peek() != null) {
parserContexts.peek().add(field);
@@ -500,11 +500,11 @@ public class MessageFormatListener extends MSpecBaseListener implements LazyType
List<Argument> parserArguments = new LinkedList<>();
// For DataIO types, add all the arguments from the parent type.
- if (!(ctx.parent.parent.parent.parent instanceof MSpecParser.ComplexTypeContext)
+/* if (!(ctx.parent.parent.parent.parent instanceof MSpecParser.ComplexTypeContext)
&& ((MSpecParser.ComplexTypeContext) ctx.parent.parent.parent).params != null) {
parserArguments.addAll(getParserArguments(
((MSpecParser.ComplexTypeContext) ctx.parent.parent.parent).params.argument()));
- }
+ }*/
// Add all eventually existing local arguments.
if (ctx.argumentList() != null) {
parserArguments.addAll(getParserArguments(ctx.argumentList().argument()));
@@ -521,7 +521,11 @@ public class MessageFormatListener extends MSpecBaseListener implements LazyType
DefaultDiscriminatedComplexTypeDefinition type =
new DefaultDiscriminatedComplexTypeDefinition(typeName, attributes, parserArguments,
discriminatorValues, parserContexts.pop());
- dispatchType(typeName, type);
+
+ // For DataIO we don't need to generate the sub-types as these will be PlcValues.
+ if(!(ctx.parent.parent instanceof MSpecParser.DataIoDefinitionContext)) {
+ dispatchType(typeName, type);
+ }
// Add the type to the switch field definition.
DefaultSwitchField switchField = getSwitchField();
diff --git a/code-generation/protocol-test/src/main/resources/protocols/test/test.mspec b/code-generation/protocol-test/src/main/resources/protocols/test/test.mspec
index ec3e21f..308f14a 100644
--- a/code-generation/protocol-test/src/main/resources/protocols/test/test.mspec
+++ b/code-generation/protocol-test/src/main/resources/protocols/test/test.mspec
@@ -141,10 +141,10 @@
]
[type ArrayTypeTest
- [array bit bitField count '5']
- [array int 8 intField count '5']
- [array uint 8 uintField count '5']
- [array float 32 floatField count '5']
+ [array bit bitField count '5']
+ [array int 8 intField count '5']
+ [array uint 8 uintField count '5']
+ [array float 32 floatField count '5']
[array float 64 doubleField count '5']
[array string 8 stringField count '5']
]
diff --git a/pom.xml b/pom.xml
index 75760bc..b509f78 100644
--- a/pom.xml
+++ b/pom.xml
@@ -165,7 +165,7 @@
<asciidoctorj.diagram.version>2.1.2</asciidoctorj.diagram.version>
<skip-code-generation-tests>false</skip-code-generation-tests>
- <skip-dependency-cve-scan>false</skip-dependency-cve-scan>
+ <skip-dependency-cve-scan>true</skip-dependency-cve-scan>
</properties>
<modules>