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
         ]