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/06/04 19:33:51 UTC

[plc4x] branch feature/code-gen updated (fab6cb9 -> 87a9a46)

This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a change to branch feature/code-gen
in repository https://gitbox.apache.org/repos/asf/plc4x.git.


    from fab6cb9  - Fine-Tuning of the spec (correcting expressions, adding missing payload types to match the parameter types) - Added Array-Access to spec expressions - Made a "curPos" field available to the Jexl execution, if required - Fixed some errors in the MessageFormatListener not omitting the expression ticks - Made the plugin add the generated sources to the project sources (So they are compiled) - Implemented a first mostly working version of the ReadBuffer - Added a Test clas [...]
     new 366c908  - Implemented a Test for the Netty based original S7 driver
     new 87a9a46  - Optimized the generated code to be way more efficient while parsing

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 plc4j/drivers/s7/pom.xml                           |  6 ++
 .../java/org/apache/plc4x/java/s7/BenchmarkS7.java | 90 ++++++++++++++++++++++
 .../apache/plc4x/language/fields/ArrayField.java   |  5 --
 .../apache/plc4x/language/fields/ContextField.java | 36 ---------
 .../plc4x/language/fields/OptionalField.java       |  5 --
 .../plc4x/language/fields/PropertyField.java       |  7 ++
 .../apache/plc4x/language/fields/SimpleField.java  |  6 --
 .../code-generation/language-template-java/pom.xml |  5 ++
 .../language/java/JavaLanguageTemplateHelper.java  | 22 ++++++
 .../main/resources/templates/java/io-template.ftlh | 47 +++++++----
 .../codegenerator/parser/imaginary/Imaginary.g4    | 34 ++++----
 .../model/fields/DefaultContextField.java          | 53 -------------
 .../parser/MessageFormatListener.java              | 15 ++--
 .../src/main/resources/protocols/s7/protocol.spec  |  2 +-
 .../{ParseException.java => EvaluationHelper.java} | 31 ++++++--
 .../java/{Test.java => BenchmarkGeneratedS7.java}  | 13 +++-
 16 files changed, 224 insertions(+), 153 deletions(-)
 create mode 100644 plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/BenchmarkS7.java
 delete mode 100644 sandbox/code-generation/language-base/src/main/java/org/apache/plc4x/language/fields/ContextField.java
 delete mode 100644 sandbox/code-generation/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/DefaultContextField.java
 copy sandbox/code-generation/test-java-s7-driver/src/main/java/org/apache/plc4x/java/utils/{ParseException.java => EvaluationHelper.java} (51%)
 rename sandbox/code-generation/test-java-s7-driver/src/test/java/{Test.java => BenchmarkGeneratedS7.java} (71%)


[plc4x] 01/02: - Implemented a Test for the Netty based original S7 driver

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch feature/code-gen
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 366c90821fbad61093f1098e969f5a83b32f9da1
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Tue Jun 4 21:28:09 2019 +0200

    - Implemented a Test for the Netty based original S7 driver
---
 plc4j/drivers/s7/pom.xml                           |  6 ++
 .../java/org/apache/plc4x/java/s7/BenchmarkS7.java | 90 ++++++++++++++++++++++
 2 files changed, 96 insertions(+)

diff --git a/plc4j/drivers/s7/pom.xml b/plc4j/drivers/s7/pom.xml
index f611cb0..68b496b 100644
--- a/plc4j/drivers/s7/pom.xml
+++ b/plc4j/drivers/s7/pom.xml
@@ -112,6 +112,12 @@
       <version>0.5.0-SNAPSHOT</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>commons-codec</groupId>
+      <artifactId>commons-codec</artifactId>
+      <version>1.12</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <build>
diff --git a/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/BenchmarkS7.java b/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/BenchmarkS7.java
new file mode 100644
index 0000000..827ea3e
--- /dev/null
+++ b/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/BenchmarkS7.java
@@ -0,0 +1,90 @@
+/*
+ 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.java.s7;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.embedded.EmbeddedChannel;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.plc4x.java.base.PlcMessageToMessageCodec;
+import org.apache.plc4x.java.base.messages.PlcRequestContainer;
+import org.apache.plc4x.java.isoontcp.protocol.IsoOnTcpProtocol;
+import org.apache.plc4x.java.isotp.protocol.IsoTPProtocol;
+import org.apache.plc4x.java.isotp.protocol.model.types.TpduSize;
+import org.apache.plc4x.java.s7.netty.S7Protocol;
+import org.apache.plc4x.java.s7.netty.model.messages.S7Message;
+import org.apache.plc4x.java.s7.types.S7ControllerType;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+
+public class BenchmarkS7 {
+
+    public static void main(String[] args) throws Exception {
+        byte[] data = Hex.decodeHex("0300006702f080320100000001005600000407120a10060001032b84000160120a10020001032b840001a0120a10010001032b840001a9120a10050001032b84000150120a10020001032b84000198120a10040001032b84000140120a10020001032b84000190");
+        TimedMessageCodec timedMessageCodec = new TimedMessageCodec();
+        EmbeddedChannel channel = new EmbeddedChannel(
+            new IsoOnTcpProtocol(),
+            new IsoTPProtocol((short) 0, (short) 0, TpduSize.SIZE_512),
+            new S7Protocol((short) 1, (short) 1, (short) 512, S7ControllerType.S7_1500, null),
+            timedMessageCodec
+            );
+
+        long start = System.currentTimeMillis();
+        int numRuns = 20000;
+        for(int i = 0; i < numRuns; i++) {
+            run(data, channel, timedMessageCodec);
+        }
+        long end = System.currentTimeMillis();
+        System.out.println("Parsed " + numRuns + " packets in " + (end - start) + "ms");
+        System.out.println("That's " + ((float) (end - start) / numRuns) + "ms per packet");
+    }
+
+    public static void run(byte[] data, EmbeddedChannel channel, TimedMessageCodec timedMessageCodec) {
+        CompletableFuture<S7Message> future = new CompletableFuture<>();
+        timedMessageCodec.setFuture(future);
+        channel.writeInbound(Unpooled.wrappedBuffer(data));
+        try {
+            future.get();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static class TimedMessageCodec extends PlcMessageToMessageCodec<S7Message, PlcRequestContainer> {
+
+        CompletableFuture<S7Message> future;
+
+        public void setFuture(CompletableFuture<S7Message> future) {
+            this.future = future;
+        }
+
+        @Override
+        protected void encode(ChannelHandlerContext ctx, PlcRequestContainer msg, List<Object> out) throws Exception {
+
+        }
+
+        @Override
+        protected void decode(ChannelHandlerContext ctx, S7Message msg, List<Object> out) throws Exception {
+            future.complete(msg);
+        }
+    }
+
+}


[plc4x] 02/02: - Optimized the generated code to be way more efficient while parsing

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch feature/code-gen
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 87a9a46b0cd7b07f0cb56e83d96d1b06d9b5c34e
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Tue Jun 4 21:33:41 2019 +0200

    - Optimized the generated code to be way more efficient while parsing
---
 .../apache/plc4x/language/fields/ArrayField.java   |  5 ---
 .../apache/plc4x/language/fields/ContextField.java | 36 -----------------
 .../plc4x/language/fields/OptionalField.java       |  5 ---
 .../plc4x/language/fields/PropertyField.java       |  7 ++++
 .../apache/plc4x/language/fields/SimpleField.java  |  6 ---
 .../code-generation/language-template-java/pom.xml |  5 +++
 .../language/java/JavaLanguageTemplateHelper.java  | 22 ++++++++++
 .../main/resources/templates/java/io-template.ftlh | 47 +++++++++++++++-------
 .../codegenerator/parser/imaginary/Imaginary.g4    | 34 ++++++++--------
 .../parser/MessageFormatListener.java              | 15 +++----
 .../src/main/resources/protocols/s7/protocol.spec  |  2 +-
 .../apache/plc4x/java/utils/EvaluationHelper.java} | 40 +++++++++---------
 .../java/{Test.java => BenchmarkGeneratedS7.java}  | 13 ++++--
 13 files changed, 122 insertions(+), 115 deletions(-)

diff --git a/sandbox/code-generation/language-base/src/main/java/org/apache/plc4x/language/fields/ArrayField.java b/sandbox/code-generation/language-base/src/main/java/org/apache/plc4x/language/fields/ArrayField.java
index e79cb9b..a0af838 100644
--- a/sandbox/code-generation/language-base/src/main/java/org/apache/plc4x/language/fields/ArrayField.java
+++ b/sandbox/code-generation/language-base/src/main/java/org/apache/plc4x/language/fields/ArrayField.java
@@ -19,7 +19,6 @@
 
 package org.apache.plc4x.language.fields;
 
-import org.apache.plc4x.language.references.TypeReference;
 
 public interface ArrayField extends PropertyField {
 
@@ -27,10 +26,6 @@ public interface ArrayField extends PropertyField {
         return "array";
     }
 
-    TypeReference getType();
-
-    String getName();
-
     LengthType getLengthType();
 
     String getLengthExpression();
diff --git a/sandbox/code-generation/language-base/src/main/java/org/apache/plc4x/language/fields/ContextField.java b/sandbox/code-generation/language-base/src/main/java/org/apache/plc4x/language/fields/ContextField.java
deleted file mode 100644
index 5cb451b..0000000
--- a/sandbox/code-generation/language-base/src/main/java/org/apache/plc4x/language/fields/ContextField.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- 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.language.fields;
-
-import org.apache.plc4x.language.references.TypeReference;
-
-public interface ContextField extends Field {
-
-    default String getTypeName() {
-        return "context";
-    }
-
-    TypeReference getType();
-
-    String getName();
-
-    String getValueExpression();
-
-}
diff --git a/sandbox/code-generation/language-base/src/main/java/org/apache/plc4x/language/fields/OptionalField.java b/sandbox/code-generation/language-base/src/main/java/org/apache/plc4x/language/fields/OptionalField.java
index fad6cfd..7d0c60c 100644
--- a/sandbox/code-generation/language-base/src/main/java/org/apache/plc4x/language/fields/OptionalField.java
+++ b/sandbox/code-generation/language-base/src/main/java/org/apache/plc4x/language/fields/OptionalField.java
@@ -19,7 +19,6 @@
 
 package org.apache.plc4x.language.fields;
 
-import org.apache.plc4x.language.references.TypeReference;
 
 public interface OptionalField extends PropertyField {
 
@@ -27,10 +26,6 @@ public interface OptionalField extends PropertyField {
         return "optional";
     }
 
-    TypeReference getType();
-
-    String getName();
-
     String getConditionExpression();
 
 }
diff --git a/sandbox/code-generation/language-base/src/main/java/org/apache/plc4x/language/fields/PropertyField.java b/sandbox/code-generation/language-base/src/main/java/org/apache/plc4x/language/fields/PropertyField.java
index b6b83de..167e43d 100644
--- a/sandbox/code-generation/language-base/src/main/java/org/apache/plc4x/language/fields/PropertyField.java
+++ b/sandbox/code-generation/language-base/src/main/java/org/apache/plc4x/language/fields/PropertyField.java
@@ -19,5 +19,12 @@
 
 package org.apache.plc4x.language.fields;
 
+import org.apache.plc4x.language.references.TypeReference;
+
 public interface PropertyField extends Field {
+
+    TypeReference getType();
+
+    String getName();
+
 }
diff --git a/sandbox/code-generation/language-base/src/main/java/org/apache/plc4x/language/fields/SimpleField.java b/sandbox/code-generation/language-base/src/main/java/org/apache/plc4x/language/fields/SimpleField.java
index 2ff614d..73a34f0 100644
--- a/sandbox/code-generation/language-base/src/main/java/org/apache/plc4x/language/fields/SimpleField.java
+++ b/sandbox/code-generation/language-base/src/main/java/org/apache/plc4x/language/fields/SimpleField.java
@@ -19,16 +19,10 @@
 
 package org.apache.plc4x.language.fields;
 
-import org.apache.plc4x.language.references.TypeReference;
-
 public interface SimpleField extends PropertyField {
 
     default String getTypeName() {
         return "simple";
     }
 
-    TypeReference getType();
-
-    String getName();
-
 }
diff --git a/sandbox/code-generation/language-template-java/pom.xml b/sandbox/code-generation/language-template-java/pom.xml
index 60b1ca0..fdc791e 100644
--- a/sandbox/code-generation/language-template-java/pom.xml
+++ b/sandbox/code-generation/language-template-java/pom.xml
@@ -44,6 +44,11 @@
       <artifactId>freemarker</artifactId>
       <version>2.3.28</version>
     </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-text</artifactId>
+      <version>1.6</version>
+    </dependency>
 
     <dependency>
       <groupId>org.slf4j</groupId>
diff --git a/sandbox/code-generation/language-template-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java b/sandbox/code-generation/language-template-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
index d1c0ed9..744bc4c 100644
--- a/sandbox/code-generation/language-template-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
+++ b/sandbox/code-generation/language-template-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
@@ -19,6 +19,7 @@
 
 package org.apache.plc4x.language.java;
 
+import org.apache.commons.text.WordUtils;
 import org.apache.plc4x.language.definitions.DiscriminatedComplexTypeDefinition;
 import org.apache.plc4x.language.definitions.TypeDefinition;
 import org.apache.plc4x.language.fields.ArrayField;
@@ -26,6 +27,9 @@ import org.apache.plc4x.language.references.ComplexTypeReference;
 import org.apache.plc4x.language.references.SimpleTypeReference;
 import org.apache.plc4x.language.references.TypeReference;
 
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 public class JavaLanguageTemplateHelper {
 
     public String getLanguageTypeNameForSpecType(TypeReference typeReference) {
@@ -253,4 +257,22 @@ public class JavaLanguageTemplateHelper {
         return arrayField.getLengthType() == ArrayField.LengthType.COUNT;
     }
 
+    public String toReadExpression(String expression) {
+        StringBuilder sb = new StringBuilder();
+        Pattern pattern = Pattern.compile("([^\\.]*)\\.([a-zA-Z\\d]+)(.*)");
+        Matcher matcher;
+        while ((matcher = pattern.matcher(expression)).matches()) {
+            String prefix = matcher.group(1);
+            String middle = matcher.group(2);
+            sb.append(prefix).append(".get").append(WordUtils.capitalize(middle)).append("()");
+            expression = matcher.group(3);
+        }
+        sb.append(expression);
+        return sb.toString();
+    }
+
+    public String toWriteExpression(String expression) {
+        return null;
+    }
+
 }
diff --git a/sandbox/code-generation/language-template-java/src/main/resources/templates/java/io-template.ftlh b/sandbox/code-generation/language-template-java/src/main/resources/templates/java/io-template.ftlh
index fb45225..f167a8a 100644
--- a/sandbox/code-generation/language-template-java/src/main/resources/templates/java/io-template.ftlh
+++ b/sandbox/code-generation/language-template-java/src/main/resources/templates/java/io-template.ftlh
@@ -40,6 +40,7 @@ package ${packageName}.io;
 
 import ${packageName}.*;
 import org.apache.commons.jexl3.*;
+import org.apache.plc4x.java.utils.EvaluationHelper;
 import org.apache.plc4x.java.utils.ReadBuffer;
 import org.apache.plc4x.java.utils.ParseException;
 import org.apache.plc4x.java.utils.WriteBuffer;
@@ -54,9 +55,37 @@ public class ${typeName}IO  {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(${typeName}IO.class);
 
+<#assign needJexl=false>
+<#list type.fields as field>
+<#switch field.typeName>
+    <#case "array">
+    private static JexlExpression ex${field.name?cap_first};
+    <#assign needJexl=true>
+    <#break>
+    <#case "optional">
+    private static JexlExpression ex${field.name?cap_first};
+    <#assign needJexl=true>
+    <#break>
+    </#switch>
+</#list>
+<#if needJexl>
+    static {
+        JexlEngine jexl = new JexlBuilder().create();
+<#list type.fields as field>
+<#switch field.typeName>
+    <#case "array">
+        ex${field.name?cap_first} = jexl.createExpression("${field.lengthExpression}");
+        <#break>
+    <#case "optional">
+        ex${field.name?cap_first} = jexl.createExpression("${field.conditionExpression}");
+        <#break>
+</#switch>
+</#list>
+    }
+</#if>
+
     public static <#if helper.isDiscriminatedType(type)>${typeName}Builder<#else>${typeName}</#if> parse(ReadBuffer io<#if type.parserArguments?has_content>, <#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForSpecType(parserArgument.type)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) throws ParseException {
         int startPos = io.getPos();
-        JexlEngine jexl = new JexlBuilder().create();
         JexlContext jc = new MapContext();
         <#if type.parserArguments?has_content>
         <#list type.parserArguments as parserArgument>
@@ -67,11 +96,10 @@ public class ${typeName}IO  {
     <#case "array">
 
         // Array field
-        JexlExpression ex${field.name} = jexl.createExpression("${field.lengthExpression}");
         <#if field.lengthExpression?contains("curPos")>
         jc.set("curPos", io.getPos() - startPos);
         </#if>
-        int size = Integer.valueOf(ex${field.name}.evaluate(jc).toString());
+        int size = Integer.valueOf(ex${field.name?cap_first}.evaluate(jc).toString());
         <#if helper.isCountArray(field)>
         ${helper.getLanguageTypeNameForSpecType(field.type)}[] ${field.name} = new ${helper.getLanguageTypeNameForSpecType(field.type)}[size];
         for(int i = 0; i < size; i++) {
@@ -96,13 +124,6 @@ public class ${typeName}IO  {
         }
         jc.set("${field.name}", ${field.name});
         <#break>
-    <#case "context">
-
-        // Context Field (Artificial value not retrieved by the input, but the context)
-        JexlExpression ex${field.name?cap_first} = jexl.createExpression("${(field.valueExpression?replace("\"", "\\\"")?no_esc)}");
-        ${helper.getLanguageTypeNameForSpecType(field.type)} ${field.name} = (${helper.getLanguageTypeNameForSpecType(field.type)}) ex${field.name?cap_first}.evaluate(jc);
-        jc.set("${field.name}", ${field.name});
-        <#break>
     <#case "discriminator">
 
         // Discriminator Field (Used as input to a switch field)
@@ -119,7 +140,6 @@ public class ${typeName}IO  {
 
         // Optional Field (Can be skipped, if a given expression evaluates to false)
         ${helper.getLanguageTypeNameForSpecType(field.type)} ${field.name} = ${helper.getNullValueForType(field.type)};
-        JexlExpression ex${field.name?cap_first} = jexl.createExpression("${field.conditionExpression}");
         if(ex${field.name?cap_first}.evaluate(jc) == Boolean.TRUE) {
             ${field.name} = <#if helper.isSimpleType(field.type)>io.${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name}IO.parse(io);</#if>;
         }
@@ -146,10 +166,9 @@ public class ${typeName}IO  {
         // Switch field (Depending on the discriminator values, passes the instantiation to a sub-type)
         ${typeName}Builder builder = null;
         <#list field.cases as case>
-        JexlExpression ex${case.name} = jexl.createExpression("<#list case.discriminatorValues as discriminatorValue>(${field.discriminatorNames[discriminatorValue?index]} == ${discriminatorValue})<#sep> && </#sep></#list>");
-        if(ex${case.name}.evaluate(jc) == Boolean.TRUE) {
+        if(<#list case.discriminatorValues as discriminatorValue>EvaluationHelper.equals(${helper.toReadExpression(field.discriminatorNames[discriminatorValue?index])}, ${discriminatorValue})<#sep> && </#sep></#list>) {
             builder = ${case.name}IO.parse(io<#if type.parserArguments?has_content>, <#list type.parserArguments as parserArgument>${parserArgument.name}<#sep>, </#sep></#list></#if>);
-        }
+        }<#sep> else </#sep>
         </#list>
         if (builder == null) {
             throw new ParseException("Unsupported case for discriminated type");
diff --git a/sandbox/code-generation/plc4x-maven-plugin/src/main/antlr4/org/apache/plc4x/codegenerator/parser/imaginary/Imaginary.g4 b/sandbox/code-generation/plc4x-maven-plugin/src/main/antlr4/org/apache/plc4x/codegenerator/parser/imaginary/Imaginary.g4
index 4671814..6a866a4 100644
--- a/sandbox/code-generation/plc4x-maven-plugin/src/main/antlr4/org/apache/plc4x/codegenerator/parser/imaginary/Imaginary.g4
+++ b/sandbox/code-generation/plc4x-maven-plugin/src/main/antlr4/org/apache/plc4x/codegenerator/parser/imaginary/Imaginary.g4
@@ -1,4 +1,22 @@
 grammar Imaginary;
+/*
+ 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.
+*/
 
 file
  : complexTypeDefinition* EOF
@@ -22,7 +40,6 @@ fieldDefinition
 field
  : arrayField
  | constField
- | contextField
  | discriminatorField
  | simpleField
  | implicitField
@@ -39,10 +56,6 @@ constField
  : K_CONST type=dataType name=idExpression expected=expression
  ;
 
-contextField
- : K_CONTEXT type=dataType name=idExpression valueExpression=expression
- ;
-
 discriminatorField
  : K_DISCRIMINATOR type=dataType name=idExpression
  ;
@@ -112,10 +125,6 @@ innerExpression
  | '"' innerExpression '"'
  ;
 
-context
- : IDENTIFIER ':' expression (',' IDENTIFIER ':' expression)*
- ;
-
 COMMENT
  : K_COMMENT [a-zA-Z0-9,.'":()/ \t\r\n\u000C-]*
  | '//' [a-zA-Z0-9,.'":()/ \t-]*
@@ -136,13 +145,6 @@ fragment HexDigit
  : [0-9a-fA-F]
 ;
 
-modifier
- : K_CONST
- | K_RESERVED
- | K_IMPLICIT
- | K_EMBEDDED
- ;
-
 arrayType
  : K_COUNT
  | K_LENGTH
diff --git a/sandbox/code-generation/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatListener.java b/sandbox/code-generation/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatListener.java
index be438b5..001888c 100644
--- a/sandbox/code-generation/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatListener.java
+++ b/sandbox/code-generation/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatListener.java
@@ -111,15 +111,6 @@ public class MessageFormatListener extends ImaginaryBaseListener {
     }
 
     @Override
-    public void enterContextField(ImaginaryParser.ContextFieldContext ctx) {
-        SimpleTypeReference type = getSimpleTypeReference(ctx.type);
-        String name = ctx.name.id.getText();
-        String valueExpression = ctx.valueExpression.expr.getText();
-        Field field = new DefaultContextField(type, name, valueExpression);
-        parserContexts.peek().add(field);
-    }
-
-    @Override
     public void enterDiscriminatorField(ImaginaryParser.DiscriminatorFieldContext ctx) {
         SimpleTypeReference type = getSimpleTypeReference(ctx.type);
         String name = ctx.name.id.getText();
@@ -209,6 +200,12 @@ public class MessageFormatListener extends ImaginaryBaseListener {
         complexTypes.put(typeName, type);
     }
 
+    /*@Override
+    public void exitExpression(ImaginaryParser.ExpressionContext ctx) {
+        ImaginaryParser.InnerExpressionContext expressionContext = ctx.innerExpression();
+        super.exitExpression(ctx);
+    }*/
+
     private TypeReference getTypeReference(ImaginaryParser.TypeReferenceContext ctx) {
         if(ctx.simpleTypeReference != null) {
             SimpleTypeReference.SimpleBaseType simpleBaseType = SimpleTypeReference.SimpleBaseType.valueOf(
diff --git a/sandbox/code-generation/protocol-s7/src/main/resources/protocols/s7/protocol.spec b/sandbox/code-generation/protocol-s7/src/main/resources/protocols/s7/protocol.spec
index a84cdcb..66e9fe9 100644
--- a/sandbox/code-generation/protocol-s7/src/main/resources/protocols/s7/protocol.spec
+++ b/sandbox/code-generation/protocol-s7/src/main/resources/protocols/s7/protocol.spec
@@ -14,7 +14,7 @@
 ////////////////////////////////////////////////////////////////
 
 [discriminatedType 'COTPPacket'
-    [implicit      uint 8 'headerLength' 'this.size - (payload.size + 1)']
+    [implicit      uint 8 'headerLength' 'size - (payload.size + 1)']
     [discriminator uint 8 'tpduCode']
     [typeSwitch 'tpduCode'
         ['0xF0' COTPPacketData
diff --git a/sandbox/code-generation/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/DefaultContextField.java b/sandbox/code-generation/test-java-s7-driver/src/main/java/org/apache/plc4x/java/utils/EvaluationHelper.java
similarity index 50%
rename from sandbox/code-generation/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/DefaultContextField.java
rename to sandbox/code-generation/test-java-s7-driver/src/main/java/org/apache/plc4x/java/utils/EvaluationHelper.java
index f9ad5c8..8e62d79 100644
--- a/sandbox/code-generation/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/DefaultContextField.java
+++ b/sandbox/code-generation/test-java-s7-driver/src/main/java/org/apache/plc4x/java/utils/EvaluationHelper.java
@@ -17,37 +17,37 @@
  under the License.
  */
 
-package org.apache.plc4x.plugins.codegenerator.model.fields;
+package org.apache.plc4x.java.utils;
 
-import org.apache.plc4x.language.fields.ContextField;
-import org.apache.plc4x.language.references.TypeReference;
+public class EvaluationHelper {
 
-public class DefaultContextField implements ContextField {
-
-    private final TypeReference type;
-    private final String name;
-    private final String valueExpression;
+    public static boolean equals(Object val1, Object val2) {
+        if(val1 instanceof Number && val2 instanceof Number) {
+            Number number1 = (Number) val1;
+            Number number2 = (Number) val2;
+            return number1.doubleValue() == number2.doubleValue();
+        }
+        return false;
+    }
 
-    public DefaultContextField(TypeReference type, String name, String valueExpression) {
-        this.type = type;
-        this.name = name;
-        this.valueExpression = valueExpression;
+    public static boolean notEquals(Object val1, Object val2) {
+        return true;
     }
 
-    public TypeReference getType() {
-        return type;
+    public static boolean greater(Object val1, Object val2) {
+        return true;
     }
 
-    public String getName() {
-        return name;
+    public static boolean greaterEquals(Object val1, Object val2) {
+        return true;
     }
 
-    public String getValueExpression() {
-        return valueExpression;
+    public static boolean smaller(Object val1, Object val2) {
+        return true;
     }
 
-    public String[] getParams() {
-        return new String[0];
+    public static boolean smallerEquals(Object val1, Object val2) {
+        return true;
     }
 
 }
diff --git a/sandbox/code-generation/test-java-s7-driver/src/test/java/Test.java b/sandbox/code-generation/test-java-s7-driver/src/test/java/BenchmarkGeneratedS7.java
similarity index 71%
rename from sandbox/code-generation/test-java-s7-driver/src/test/java/Test.java
rename to sandbox/code-generation/test-java-s7-driver/src/test/java/BenchmarkGeneratedS7.java
index 28598d5..9ba58b3 100644
--- a/sandbox/code-generation/test-java-s7-driver/src/test/java/Test.java
+++ b/sandbox/code-generation/test-java-s7-driver/src/test/java/BenchmarkGeneratedS7.java
@@ -22,12 +22,19 @@ import org.apache.plc4x.java.s7.TPKTPacket;
 import org.apache.plc4x.java.s7.io.TPKTPacketIO;
 import org.apache.plc4x.java.utils.ReadBuffer;
 
-public class Test {
+public class BenchmarkGeneratedS7 {
 
     public static void main(String[] args) throws Exception {
         byte[] data = Hex.decodeHex("0300006702f080320100000001005600000407120a10060001032b84000160120a10020001032b840001a0120a10010001032b840001a9120a10050001032b84000150120a10020001032b84000198120a10040001032b84000140120a10020001032b84000190");
-        ReadBuffer buf = new ReadBuffer(data);
-        TPKTPacket packet = TPKTPacketIO.parse(buf);
+        long start = System.currentTimeMillis();
+        int numRuns = 20000;
+        for(int i = 0; i < numRuns; i++) {
+            ReadBuffer buf = new ReadBuffer(data);
+            TPKTPacket packet = TPKTPacketIO.parse(buf);
+        }
+        long end = System.currentTimeMillis();
+        System.out.println("Parsed " + numRuns + " packets in " + (end - start) + "ms");
+        System.out.println("That's " + ((float) (end - start) / numRuns) + "ms per packet");
     }
 
 }