You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by sr...@apache.org on 2022/08/04 14:22:37 UTC
[plc4x] branch develop updated: feat(codegen/plc4j): save reserved in case they differ so they can be written out again using the same value
This is an automated email from the ASF dual-hosted git repository.
sruehl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/develop by this push:
new 8baeacf1d feat(codegen/plc4j): save reserved in case they differ so they can be written out again using the same value
8baeacf1d is described below
commit 8baeacf1da74042dd41205cc9620b9523af37c0d
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Thu Aug 4 16:22:29 2022 +0200
feat(codegen/plc4j): save reserved in case they differ so they can be written out again using the same value
---
.../templates/java/complex-type-template.java.ftlh | 126 +++++++++++++++++++--
.../src/main/resources/protocols/test/test.mspec | 10 ++
.../spi/codegen/fields/FieldReaderReserved.java | 3 +-
3 files changed, 127 insertions(+), 12 deletions(-)
diff --git a/code-generation/language-java/src/main/resources/templates/java/complex-type-template.java.ftlh b/code-generation/language-java/src/main/resources/templates/java/complex-type-template.java.ftlh
index c23bd040d..4f2a872f1 100644
--- a/code-generation/language-java/src/main/resources/templates/java/complex-type-template.java.ftlh
+++ b/code-generation/language-java/src/main/resources/templates/java/complex-type-template.java.ftlh
@@ -136,6 +136,13 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
protected final ${helper.getLanguageTypeNameForTypeReference(parserArgument.type)} ${parserArgument.name};
</#list>
</#if>
+<#assign reservedFields=type.getFields()?filter(f->f.isReservedField())>
+<#if reservedFields?has_content>
+ // Reserved Fields
+ <#list reservedFields as reservedField>
+ private ${helper.getLanguageTypeNameForTypeReference(reservedField.asReservedField().orElseThrow().type, false)} reservedField${reservedField?index};
+ </#list>
+</#if>
<#-- getAllPropertyFields() returns not only the property fields of this type but also of it's parents -->
<@compress single_line=true>
@@ -235,6 +242,7 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
<#else>
int startPos = positionAware.getPos();
writeBuffer.pushContext("${type.name}");
+ <#assign reservedFieldIndex=0>
<#list type.fields as field>
<#switch field.typeName>
<#case "array">
@@ -335,7 +343,7 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
<#assign typedField = field.asTypedField().orElseThrow()>
// Reserved Field (reserved)
- writeReservedField("reserved", ${helper.getReservedValue(reservedField)}, ${helper.getDataWriterCall(typedField.type, "reserved")});
+ writeReservedField("reserved", reservedField${reservedFieldIndex}!=null?reservedField${reservedFieldIndex}:${helper.getReservedValue(reservedField)}, ${helper.getDataWriterCall(typedField.type, "reserved")});<#assign reservedFieldIndex=reservedFieldIndex+1>
<#break>
<#case "simple">
<#assign simpleField = field.asSimpleField().orElseThrow()>
@@ -588,6 +596,7 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
PositionAware positionAware = readBuffer;
int startPos = positionAware.getPos();
int curPos;
+ <#assign reservedFieldIndex=0>
<#list type.fields as field>
<#switch field.typeName>
<#case "array">
@@ -696,7 +705,7 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
<#assign reservedField = field.asReservedField().orElseThrow()>
<#assign typedField = field.asTypedField().orElseThrow()>
- read${field.typeName?cap_first}Field("reserved", ${helper.getDataReaderCall(typedField.type)}, ${helper.getReservedValue(reservedField)}${helper.getFieldOptions(typedField, parserArguments)});
+ ${helper.getLanguageTypeNameForTypeReference(reservedField.type, false)} reservedField${reservedFieldIndex}<#assign reservedFieldIndex=reservedFieldIndex+1> = read${field.typeName?cap_first}Field("reserved", ${helper.getDataReaderCall(typedField.type)}, ${helper.getReservedValue(reservedField)}${helper.getFieldOptions(typedField, parserArguments)});
<#break>
<#case "simple">
<#assign simpleField = field.asSimpleField().orElseThrow()>
@@ -779,17 +788,69 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
readBuffer.closeContext("${type.name}");
// Create the instance
<#if type.isDiscriminatedChildTypeDefinition()>
- return new ${type.name}Builder(<#list type.propertyFields as field>${field.name}<#sep>, </#sep></#list><#if filteredParserArguments?has_content><#if type.propertyFields?has_content>, </#if><#list filteredParserArguments as arg>${arg.name}<#sep>, </#sep></#list></#if>);
+ return new ${type.name}Builder(
+ <#list type.propertyFields as field>
+ ${field.name}<#sep>, </#sep>
+ </#list>
+ <#if filteredParserArguments?has_content>
+ <#if type.propertyFields?has_content>, </#if>
+ <#list filteredParserArguments as arg>${arg.name}<#sep>, </#sep>
+ </#list>
+ </#if>
+ <#if (type.propertyFields?has_content || filteredParentParserArguments?has_content) && reservedFields?has_content>,</#if>
+ <#list reservedFields as reservedField>
+ reservedField${reservedField?index}<#sep>, </#sep>
+ </#list>
+ );
<#elseif type.isDiscriminatedParentTypeDefinition()>
- return builder.build(<#list type.propertyFields as field>${field.name}<#sep>, </#sep></#list><#if filteredParserArguments?has_content><#if type.propertyFields?has_content>, </#if><#list filteredParserArguments as arg>${arg.name}<#sep>, </#sep></#list></#if>);
+ ${type.name} ${type.name?uncap_first} = builder.build(
+ <#list type.propertyFields as field>
+ ${field.name}<#sep>, </#sep>
+ </#list>
+ <#if filteredParserArguments?has_content>
+ <#if type.propertyFields?has_content>, </#if>
+ <#list filteredParserArguments as arg>
+ ${arg.name}<#sep>, </#sep>
+ </#list>
+ </#if>
+ );
+ <#list reservedFields as reservedField>
+ ${type.name?uncap_first}.reservedField${reservedField?index} = reservedField${reservedField?index};
+ </#list>
+ return ${type.name?uncap_first};
<#else>
- return new ${type.name}(<#list type.propertyFields as field>${field.name}<#sep>, </#sep></#list><#if filteredParserArguments?has_content><#if type.propertyFields?has_content>, </#if><#list filteredParserArguments as arg>${arg.name}<#sep>, </#sep></#list></#if>);
+ ${type.name} ${type.name?uncap_first};
+ ${type.name?uncap_first} = new ${type.name}(
+ <#list type.propertyFields as field>
+ ${field.name}<#sep>, </#sep>
+ </#list>
+ <#if filteredParserArguments?has_content>
+ <#if type.propertyFields?has_content>, </#if>
+ <#list filteredParserArguments as arg>
+ ${arg.name}<#sep>, </#sep>
+ </#list>
+ </#if>
+ );
+ <#list reservedFields as reservedField>
+ ${type.name?uncap_first}.reservedField${reservedField?index} = reservedField${reservedField?index};
+ </#list>
+ return ${type.name?uncap_first};
</#if>
}
<#if type.isDiscriminatedParentTypeDefinition()>
public static interface ${type.name}Builder {
- ${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>);
+ ${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>
@@ -797,16 +858,33 @@ 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 ${helper.getLanguageTypeNameForField(field)} ${field.name};
+ private final ${helper.getLanguageTypeNameForField(field)} ${field.name};
</#list>
</#if>
<#if filteredParserArguments?has_content>
<#list filteredParserArguments as arg>
- private final ${helper.getLanguageTypeNameForTypeReference(arg.type)} ${arg.name};
+ private final ${helper.getLanguageTypeNameForTypeReference(arg.type)} ${arg.name};
</#list>
</#if>
+ <#list reservedFields as reservedField>
+ private final ${helper.getLanguageTypeNameForTypeReference(reservedField.type, false)} reservedField${reservedField?index};
+ </#list>
- 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>) {
+ 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>
+ <#if (type.propertyFields?has_content || filteredParentParserArguments?has_content) && reservedFields?has_content>,</#if>
+ <#list reservedFields as reservedField>
+ ${helper.getLanguageTypeNameForTypeReference(reservedField.type, false)} reservedField${reservedField?index}<#sep>, </#sep>
+ </#list>
+ ) {
<#list type.propertyFields as field>
this.${field.name} = ${field.name};
</#list>
@@ -815,10 +893,36 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
this.${arg.name} = ${arg.name};
</#list>
</#if>
+ <#list reservedFields as reservedField>
+ this.reservedField${reservedField?index} = reservedField${reservedField?index};
+ </#list>
}
- 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>);
+ 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>, </#sep>
+ </#list>
+ </#if>
+ ) {
+ ${type.name} ${type.name?uncap_first} = 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>);
+ <#list reservedFields as reservedField>
+ ${type.name?uncap_first}.reservedField${reservedField?index} = reservedField${reservedField?index};
+ </#list>
+ return ${type.name?uncap_first};
}
}
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 ad2c16aae..7e3ecdc45 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
@@ -202,6 +202,16 @@
[reserved uint 8 '0x00']
]
+[type ReservedTypeTestParent
+ [reserved uint 8 '0x00']
+ [simple uint 8 simpleField]
+ [typeSwitch simpleField
+ ['0' ReservedTypeTestChild
+ [reserved uint 8 '0x00']
+ ]
+ ]
+]
+
// TODO: So far only trouble in GO, C seems OK.
[type VirtualFieldTest
[simple uint 8 simpleField]
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/fields/FieldReaderReserved.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/fields/FieldReaderReserved.java
index c3c654528..2c0e3e439 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/fields/FieldReaderReserved.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/fields/FieldReaderReserved.java
@@ -36,8 +36,9 @@ public class FieldReaderReserved<T> implements FieldCommons {
T reserved = dataReader.read(logicalName, readerArgs);
if (!Objects.equals(reserved, referenceValue)) {
LOGGER.info("Expected constant value {} but got {} for reserved field.", referenceValue, reserved);
+ return reserved;
}
- return reserved;
+ return null;
}
}