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 2019/08/07 08:47:57 UTC
[plc4x] 10/17: - Some major tweaking of how the mspec handles
discriminator types - Added arguments to the serialize methods,
the same way they were added to the parse methods - made the mspec parser
allow array index expressions
This is an automated email from the ASF dual-hosted git repository.
cdutz pushed a commit to branch feature/implement-df1-driver
in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit 17d61a30eff1aa5c6f73ad2506cdbd63a3a6c49d
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Wed Jul 31 11:59:12 2019 +0200
- Some major tweaking of how the mspec handles discriminator types
- Added arguments to the serialize methods, the same way they were added to the parse methods
- made the mspec parser allow array index expressions
---
.../language/java/JavaLanguageTemplateHelper.java | 55 +++++++++++++++++++---
.../main/resources/templates/java/io-template.ftlh | 19 +++++---
.../resources/templates/java/pojo-template.ftlh | 3 +-
.../plugins/codegenerator/language/mspec/MSpec.g4 | 1 +
.../mspec/expression/ExpressionStringListener.java | 2 +-
.../DefaultDiscriminatedComplexTypeDefinition.java | 9 ++++
.../main/resources/protocols/df1/protocol.mspec | 2 +-
7 files changed, 75 insertions(+), 16 deletions(-)
diff --git a/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java b/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
index 25ec787..bf293a6 100644
--- a/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
+++ b/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
@@ -21,6 +21,7 @@ package org.apache.plc4x.language.java;
import org.apache.commons.text.WordUtils;
import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.FreemarkerLanguageTemplateHelper;
+import org.apache.plc4x.plugins.codegenerator.types.definitions.Argument;
import org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition;
import org.apache.plc4x.plugins.codegenerator.types.definitions.DiscriminatedComplexTypeDefinition;
import org.apache.plc4x.plugins.codegenerator.types.definitions.TypeDefinition;
@@ -393,8 +394,8 @@ public class JavaLanguageTemplateHelper implements FreemarkerLanguageTemplateHel
return toExpression(term, this::toVariableDeserializationExpression);
}
- public String toSerializationExpression(Term term) {
- return toExpression(term, this::toVariableSerializationExpression);
+ public String toSerializationExpression(Term term, Argument[] parserArguments) {
+ return toExpression(term, term1 -> toVariableSerializationExpression(term1, parserArguments));
}
private String toExpression(Term term, Function<Term, String> variableExpressionGenerator) {
@@ -481,7 +482,7 @@ public class JavaLanguageTemplateHelper implements FreemarkerLanguageTemplateHel
return vl.getName() + ((vl.getChild() != null) ? "." + toVariableExpressionRest(vl.getChild()) : "");
}
- private String toVariableSerializationExpression(Term term) {
+ private String toVariableSerializationExpression(Term term, Argument[] parserArguments) {
VariableLiteral vl = (VariableLiteral) term;
if("STATIC_CALL".equals(vl.getName())) {
StringBuilder sb = new StringBuilder();
@@ -497,7 +498,21 @@ public class JavaLanguageTemplateHelper implements FreemarkerLanguageTemplateHel
sb.append(", ");
}
if(arg instanceof VariableLiteral) {
- sb.append(toVariableSerializationExpression(arg));
+ VariableLiteral va = (VariableLiteral) arg;
+ boolean isSerializerArg = false;
+ if(parserArguments != null) {
+ for (Argument parserArgument : parserArguments) {
+ if (parserArgument.getName().equals(va.getName())) {
+ isSerializerArg = true;
+ break;
+ }
+ }
+ }
+ if(isSerializerArg) {
+ sb.append(va.getName() + ((va.getChild() != null) ? "." + toVariableExpressionRest(va.getChild()) : ""));
+ } else {
+ sb.append(toVariableSerializationExpression(va, null));
+ }
} else if(arg instanceof StringLiteral) {
sb.append(((StringLiteral) arg).getValue());
}
@@ -515,8 +530,23 @@ public class JavaLanguageTemplateHelper implements FreemarkerLanguageTemplateHel
if(!firstArg) {
sb.append(", ");
}
+
if(arg instanceof VariableLiteral) {
- sb.append(toVariableSerializationExpression(arg));
+ VariableLiteral va = (VariableLiteral) arg;
+ boolean isSerializerArg = false;
+ if(parserArguments != null) {
+ for (Argument parserArgument : parserArguments) {
+ if (parserArgument.getName().equals(va.getName())) {
+ isSerializerArg = true;
+ break;
+ }
+ }
+ }
+ if(isSerializerArg) {
+ sb.append(va.getName() + ((va.getChild() != null) ? "." + toVariableExpressionRest(va.getChild()) : ""));
+ } else {
+ sb.append(toVariableSerializationExpression(va, null));
+ }
} else if(arg instanceof StringLiteral) {
sb.append(((StringLiteral) arg).getValue());
}
@@ -526,7 +556,20 @@ public class JavaLanguageTemplateHelper implements FreemarkerLanguageTemplateHel
}
return sb.toString();
}
- return "value." + toVariableExpressionRest(vl);
+ boolean isSerializerArg = false;
+ if(parserArguments != null) {
+ for (Argument parserArgument : parserArguments) {
+ if (parserArgument.getName().equals(vl.getName())) {
+ isSerializerArg = true;
+ break;
+ }
+ }
+ }
+ if(isSerializerArg) {
+ return vl.getName() + ((vl.getChild() != null) ? "." + toVariableExpressionRest(vl.getChild()) : "");
+ } else {
+ return "value." + toVariableExpressionRest(vl);
+ }
}
private String toVariableExpressionRest(VariableLiteral vl) {
diff --git a/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh b/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh
index cf5a134..a76859e 100644
--- a/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh
+++ b/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh
@@ -206,21 +206,25 @@ public class ${typeName}IO implements MessageIO<${typeName}<#if helper.isDiscrim
<#case "discriminator">
// Discriminator Field (Used as input to a switch field)
- io.${helper.getWriteBufferReadMethodCall(field.type, "value.getDiscriminatorValues()[0]")};
+ ${helper.getLanguageTypeNameForField(field)} ${field.name} = (${helper.getLanguageTypeNameForField(field)}) value.getDiscriminatorValues()[0];
+ io.${helper.getWriteBufferReadMethodCall(field.type, "(" + field.name + ")")};
<#break>
<#case "implicit">
// Implicit Field (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
- io.${helper.getWriteBufferReadMethodCall(field.type, "(" + helper.toSerializationExpression(field.serializationExpression) + ")")?no_esc};
+ ${helper.getLanguageTypeNameForField(field)} ${field.name} = (${helper.getLanguageTypeNameForField(field)}) (${helper.toSerializationExpression(field.serializationExpression, type.parserArguments)});
+ io.${helper.getWriteBufferReadMethodCall(field.type, "(" + field.name + ")")?no_esc};
<#break>
<#case "optional">
// Optional Field (Can be skipped, if the value is null)
+ ${helper.getLanguageTypeNameForField(field)} ${field.name} = null;
if(value.get${field.name?cap_first}() != null) {
+ ${field.name} = (${helper.getLanguageTypeNameForField(field)}) value.get${field.name?cap_first}();
<#if helper.isSimpleType(field.type)>
- io.${helper.getWriteBufferReadMethodCall(field.type, "value.get" + field.name?cap_first + "()")};
+ io.${helper.getWriteBufferReadMethodCall(field.type, "(" + field.name + ")")};
<#else>
- ${field.type.name?uncap_first}IO.serialize(io, value.get${field.name?cap_first}());
+ ${field.type.name?uncap_first}IO.serialize(io, ${field.name});
</#if>
}
<#break>
@@ -232,10 +236,11 @@ public class ${typeName}IO implements MessageIO<${typeName}<#if helper.isDiscrim
<#case "simple">
// Simple field
+ ${helper.getLanguageTypeNameForField(field)} ${field.name} = (${helper.getLanguageTypeNameForField(field)}) value.get${field.name?cap_first}();
<#if helper.isSimpleType(field.type)>
- io.${helper.getWriteBufferReadMethodCall(field.type, "value.get" + field.name?cap_first + "()")};
+ io.${helper.getWriteBufferReadMethodCall(field.type, "(" + field.name + ")")};
<#else>
- ${field.type.name?uncap_first}IO.serialize(io, value.get${field.name?cap_first}());
+ ${field.type.name?uncap_first}IO.serialize(io, ${field.name}<#if field.params?has_content>, <#list field.params as term>(${helper.getArgumentType(field.type, term?index)}) (${helper.toDeserializationExpression(term)})<#sep>, </#sep></#list></#if>);
</#if>
<#break>
<#case "switch">
@@ -243,7 +248,7 @@ public class ${typeName}IO implements MessageIO<${typeName}<#if helper.isDiscrim
// Switch field (Depending on the discriminator values, passes the instantiation to a sub-type)
<#list field.cases as case>
if(value instanceof ${case.name}) {
- ${case.name?uncap_first}IO.serialize(io, (${case.name}) value);
+ ${case.name?uncap_first}IO.serialize(io, (${case.name}) value<#if case.parserArguments?has_content>, <#list case.parserArguments as parserArgument>${parserArgument.name}<#sep>, </#sep></#list></#if>);
}<#sep> else </#sep>
</#list>
<#break>
diff --git a/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh b/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh
index 5b095bf..d8df6ef 100644
--- a/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh
+++ b/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh
@@ -50,7 +50,8 @@ public<#if type.abstract> abstract</#if> class ${typeName}<#if type.parentType??
// Discriminator values used by the parser to determine the type to be used. All values have to apply.
public static final Object[] DISCRIMINATOR_VALUES = new Object[] {
<#list type.discriminatorValues as discriminatorValue>
- ${discriminatorValue}<#sep>, </#sep>
+ <#-- There are rare occasions where the discriminator is defined by a parser argument, in this case we currently can't detect the type -->
+ <#if type.discriminatorField??>(${helper.getLanguageTypeNameForField(type.discriminatorField)}) </#if>${discriminatorValue}<#sep>, </#sep>
</#list>
};
</#if>
diff --git a/build-utils/protocol-base-mspec/src/main/antlr4/org/apache/plc4x/plugins/codegenerator/language/mspec/MSpec.g4 b/build-utils/protocol-base-mspec/src/main/antlr4/org/apache/plc4x/plugins/codegenerator/language/mspec/MSpec.g4
index f7d6d7d..374894b 100644
--- a/build-utils/protocol-base-mspec/src/main/antlr4/org/apache/plc4x/plugins/codegenerator/language/mspec/MSpec.g4
+++ b/build-utils/protocol-base-mspec/src/main/antlr4/org/apache/plc4x/plugins/codegenerator/language/mspec/MSpec.g4
@@ -119,6 +119,7 @@ innerExpression
| INTEGER_LITERAL
| (IDENTIFIER | arrayType) ('(' (innerExpression (',' innerExpression)* )? ')')? ('[' innerExpression ']')?
| innerExpression '.' innerExpression // Field Reference or method call
+ | innerExpression '[' + INTEGER_LITERAL + ']' // Array index
| innerExpression BinaryOperator innerExpression // Addition
| '(' innerExpression ')'
| '"' innerExpression '"'
diff --git a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/expression/ExpressionStringListener.java b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/expression/ExpressionStringListener.java
index 4586e4e..903a5c8 100644
--- a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/expression/ExpressionStringListener.java
+++ b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/expression/ExpressionStringListener.java
@@ -232,7 +232,7 @@ public class ExpressionStringListener extends ExpressionBaseListener {
private VariableLiteral getVariableLiteral(ExpressionParser.IdentifierSegmentContext ctx, List<Term> args) {
String name = ctx.name.getText();
- int index = (ctx.index != null) ? Integer.valueOf(ctx.index.getText()) : VariableLiteral.NO_INDEX;
+ int index = (ctx.index != null) ? Integer.valueOf(ctx.index.getText().substring(1, ctx.index.getText().length() - 1)) : VariableLiteral.NO_INDEX;
VariableLiteral child = (ctx.rest != null) ? getVariableLiteral(ctx.rest, args) : null;
return new VariableLiteral(name, args, index, child);
}
diff --git a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultDiscriminatedComplexTypeDefinition.java b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultDiscriminatedComplexTypeDefinition.java
index ad912d1..201750a 100644
--- a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultDiscriminatedComplexTypeDefinition.java
+++ b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultDiscriminatedComplexTypeDefinition.java
@@ -21,6 +21,7 @@ package org.apache.plc4x.plugins.codegenerator.language.mspec.model.definitions;
import org.apache.plc4x.plugins.codegenerator.types.definitions.Argument;
import org.apache.plc4x.plugins.codegenerator.types.definitions.DiscriminatedComplexTypeDefinition;
+import org.apache.plc4x.plugins.codegenerator.types.fields.DiscriminatorField;
import org.apache.plc4x.plugins.codegenerator.types.fields.Field;
import java.util.List;
@@ -34,6 +35,14 @@ public class DefaultDiscriminatedComplexTypeDefinition extends DefaultComplexTyp
this.discriminatorValues = discriminatorValues;
}
+ public DiscriminatorField getDiscriminatorField() {
+ // For a discriminated type, the discriminator is always defined in the parent type,
+ // which is always a DefaultComplexTypeDefinition instance.
+ return ((DefaultComplexTypeDefinition) getParentType()).getFields().stream().filter(
+ field -> field instanceof DiscriminatorField).map(
+ field -> (DiscriminatorField) field).findFirst().orElse(null);
+ }
+
public String[] getDiscriminatorValues() {
return discriminatorValues;
}
diff --git a/protocols/df1/src/main/resources/protocols/df1/protocol.mspec b/protocols/df1/src/main/resources/protocols/df1/protocol.mspec
index f243d93..ce5a8f5 100644
--- a/protocols/df1/src/main/resources/protocols/df1/protocol.mspec
+++ b/protocols/df1/src/main/resources/protocols/df1/protocol.mspec
@@ -38,7 +38,7 @@
[field DF1Command 'command' ['payloadSize']]
]
['0x03' DF1SymbolMessageFrameEnd
- [implicit uint 16 'crc' 'STATIC_CALL("org.apache.plc4x.protocol.df1.DF1Utils.CRCCheck", messageStartSymbol.destinationAddress, messageStartSymbol.sourceAddress, messageStartSymbol.command.discriminatorValues, messageStartSymbol.command.status, messageStartSymbol.command.transactionCounter, symbolType)']
+ [implicit uint 16 'crc' 'STATIC_CALL("org.apache.plc4x.protocol.df1.DF1Utils.CRCCheck", messageStartSymbol.destinationAddress, messageStartSymbol.sourceAddress, messageStartSymbol.command.discriminatorValues, messageStartSymbol.command.status, messageStartSymbol.command.transactionCounter, discriminatorValues[0])']
]
['0x06' DF1SymbolMessageFrameACK
]