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 2020/10/06 15:21:42 UTC

[plc4x] 04/04: - Added some initial generated code together with the project files for running it in GoLand

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

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

commit 1c0fac82ae1082c6cdce2e0267e777655597fb34
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Tue Oct 6 17:21:23 2020 +0200

    - Added some initial generated code together with the project files for running it in GoLand
---
 .../plc4go => build-utils/language-go}/pom.xml     |  57 +-
 .../apache/plc4x/language/go/GoLanguageOutput.java |  75 +++
 .../language/go/GoLanguageTemplateHelper.java      | 712 +++++++++++++++++++++
 ...x.plugins.codegenerator.language.LanguageOutput |  24 +-
 .../resources/templates/go/data-io-template.ftlh   | 312 +++++++++
 .../templates/go/enum-package-info-template.ftlh   |  47 ++
 .../main/resources/templates/go/enum-template.ftlh | 115 ++++
 .../main/resources/templates/go/pojo-template.ftlh | 216 +++++++
 build-utils/pom.xml                                |   1 +
 .../hello-connectivity-mqtt/mqtt-connector.yml     |   2 +-
 .../plc4go/go/modbus/readwrite/ModbusConstants.go  |  45 ++
 .../plc4go/go/modbus/readwrite/ModbusPDU.go        |  50 ++
 .../modbus/readwrite/ModbusPDUDiagnosticRequest.go |  51 ++
 .../plc4go/go/modbus/readwrite/ModbusPDUError.go   |  47 ++
 .../readwrite/ModbusPDUGetComEventLogRequest.go    |  43 ++
 .../readwrite/ModbusPDUGetComEventLogResponse.go   |  64 ++
 .../ModbusPDUMaskWriteHoldingRegisterRequest.go    |  55 ++
 .../ModbusPDUMaskWriteHoldingRegisterResponse.go   |  55 ++
 .../modbus/readwrite/ModbusPDUReadCoilsRequest.go  |  51 ++
 .../modbus/readwrite/ModbusPDUReadCoilsResponse.go |  52 ++
 .../ModbusPDUReadDeviceIdentificationRequest.go    |  43 ++
 .../ModbusPDUReadDeviceIdentificationResponse.go   |  43 ++
 .../ModbusPDUReadDiscreteInputsRequest.go          |  51 ++
 .../ModbusPDUReadDiscreteInputsResponse.go         |  52 ++
 .../ModbusPDUReadExceptionStatusRequest.go         |  43 ++
 .../ModbusPDUReadExceptionStatusResponse.go        |  47 ++
 .../readwrite/ModbusPDUReadFifoQueueRequest.go     |  47 ++
 .../readwrite/ModbusPDUReadFifoQueueResponse.go    |  55 ++
 .../readwrite/ModbusPDUReadFileRecordRequest.go    |  54 ++
 .../ModbusPDUReadFileRecordRequestItem.go          |  58 ++
 .../readwrite/ModbusPDUReadFileRecordResponse.go   |  54 ++
 .../ModbusPDUReadFileRecordResponseItem.go         |  55 ++
 .../ModbusPDUReadHoldingRegistersRequest.go        |  51 ++
 .../ModbusPDUReadHoldingRegistersResponse.go       |  52 ++
 .../ModbusPDUReadInputRegistersRequest.go          |  51 ++
 .../ModbusPDUReadInputRegistersResponse.go         |  52 ++
 ...sPDUReadWriteMultipleHoldingRegistersRequest.go |  68 ++
 ...PDUReadWriteMultipleHoldingRegistersResponse.go |  52 ++
 .../readwrite/ModbusPDUReportServerIdRequest.go    |  43 ++
 .../readwrite/ModbusPDUReportServerIdResponse.go   |  52 ++
 .../readwrite/ModbusPDUWriteFileRecordRequest.go   |  54 ++
 .../ModbusPDUWriteFileRecordRequestItem.go         |  63 ++
 .../readwrite/ModbusPDUWriteFileRecordResponse.go  |  54 ++
 .../ModbusPDUWriteFileRecordResponseItem.go        |  63 ++
 .../ModbusPDUWriteMultipleCoilsRequest.go          |  60 ++
 .../ModbusPDUWriteMultipleCoilsResponse.go         |  51 ++
 ...odbusPDUWriteMultipleHoldingRegistersRequest.go |  60 ++
 ...dbusPDUWriteMultipleHoldingRegistersResponse.go |  51 ++
 .../readwrite/ModbusPDUWriteSingleCoilRequest.go   |  51 ++
 .../readwrite/ModbusPDUWriteSingleCoilResponse.go  |  51 ++
 .../ModbusPDUWriteSingleRegisterRequest.go         |  51 ++
 .../ModbusPDUWriteSingleRegisterResponse.go        |  51 ++
 .../plc4go/go/modbus/readwrite/ModbusSerialADU.go  |  61 ++
 .../plc4go/go/modbus/readwrite/ModbusTcpADU.go     |  60 ++
 sandbox/plc4go/go.mod                              |  18 +
 sandbox/plc4go/pom.xml                             |  92 ++-
 sandbox/plc4go/src/modbus.go                       |  16 +
 .../plc4go/src/plc4go/modbus/readwrite/Message.go  |  10 -
 sandbox/plc4go/src/plc4go/spi/Message.go           |  24 +
 sandbox/plc4go/src/plc4go/spi/ReadBuffer.go        |  22 +
 sandbox/plc4go/src/plc4go/spi/WriteBuffer.go       |  22 +
 sandbox/pom.xml                                    |   9 +
 62 files changed, 4010 insertions(+), 81 deletions(-)

diff --git a/sandbox/plc4go/pom.xml b/build-utils/language-go/pom.xml
similarity index 54%
copy from sandbox/plc4go/pom.xml
copy to build-utils/language-go/pom.xml
index 90c81e9..cb2b3ce 100644
--- a/sandbox/plc4go/pom.xml
+++ b/build-utils/language-go/pom.xml
@@ -22,36 +22,37 @@
   <modelVersion>4.0.0</modelVersion>
 
   <parent>
-    <groupId>org.apache.plc4x.sandbox</groupId>
-    <artifactId>plc4x-sandbox</artifactId>
+    <groupId>org.apache.plc4x</groupId>
+    <artifactId>plc4x-build-utils</artifactId>
     <version>0.8.0-SNAPSHOT</version>
   </parent>
 
-  <artifactId>plc4go</artifactId>
-  <packaging>pom</packaging>
-
-  <name>Sandbox: PLC4Go</name>
-  <description>Implementation of the protocol adapters for usage as Go(lang) library.</description>
-
-  <plugins>
-    <plugin>
-      <groupId>com.igormaznitsa</groupId>
-      <artifactId>mvn-golang-wrapper</artifactId>
-      <version>2.3.5</version>
-      <extensions>true</extensions>
-      <executions>
-        <execution>
-          <goals>
-            <goal>run</goal>
-          </goals>
-          <configuration>
-            <packages>
-              <package>main.go</package>
-            </packages>
-          </configuration>
-        </execution>
-      </executions>
-    </plugin>
-  </plugins>
+  <artifactId>plc4x-build-utils-language-go</artifactId>
+
+  <name>PLC4X: Build Utils: Language: Go</name>
+  <description>Code generation template for generating Go(lang) code</description>
+
+  <dependencies>
+    <!-- We are using the Freemarker module to generate Java code -->
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-build-utils-language-base-freemarker</artifactId>
+      <version>0.8.0-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.plc4x.plugins</groupId>
+      <artifactId>plc4x-code-generation-types-base</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.freemarker</groupId>
+      <artifactId>freemarker</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-text</artifactId>
+    </dependency>
+  </dependencies>
 
 </project>
\ No newline at end of file
diff --git a/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageOutput.java b/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageOutput.java
new file mode 100644
index 0000000..3c8ee09
--- /dev/null
+++ b/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageOutput.java
@@ -0,0 +1,75 @@
+/*
+ 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.go;
+
+import freemarker.template.*;
+import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.FreemarkerLanguageOutput;
+import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.FreemarkerLanguageTemplateHelper;
+import org.apache.plc4x.plugins.codegenerator.types.definitions.TypeDefinition;
+
+import java.io.*;
+import java.util.*;
+
+public class GoLanguageOutput extends FreemarkerLanguageOutput {
+
+    @Override
+    public String getName() {
+        return "Go";
+    }
+
+    @Override
+    public List<String> supportedOutputFlavors() {
+        return Arrays.asList("read-write", "read-only", "passive");
+    }
+
+    @Override
+    protected List<Template> getSpecTemplates(Configuration freemarkerConfiguration) throws IOException {
+        /*return Collections.singletonList(
+            freemarkerConfiguration.getTemplate("templates/go/enum-package-info-template.ftlh"));*/
+        return Collections.emptyList();
+    }
+
+    @Override
+    protected List<Template> getComplexTypeTemplates(Configuration freemarkerConfiguration) throws IOException {
+        return Arrays.asList(
+            freemarkerConfiguration.getTemplate("templates/go/pojo-template.ftlh")/*,
+            freemarkerConfiguration.getTemplate("templates/go/io-template.ftlh")*/);
+    }
+
+    @Override
+    protected List<Template> getEnumTypeTemplates(Configuration freemarkerConfiguration) throws IOException {
+        /*return Collections.singletonList(
+            freemarkerConfiguration.getTemplate("templates/go/enum-template.ftlh"));*/
+        return Collections.emptyList();
+    }
+
+    @Override
+    protected List<Template> getDataIoTemplates(Configuration freemarkerConfiguration) throws IOException {
+        /*return Collections.singletonList(
+            freemarkerConfiguration.getTemplate("templates/go/data-io-template.ftlh"));*/
+        return Collections.emptyList();
+    }
+
+    @Override
+    protected FreemarkerLanguageTemplateHelper getHelper(TypeDefinition thisType, String protocolName, String flavorName, Map<String, TypeDefinition> types) {
+        return new GoLanguageTemplateHelper(thisType, protocolName, flavorName, types);
+    }
+
+}
diff --git a/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageTemplateHelper.java b/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageTemplateHelper.java
new file mode 100644
index 0000000..70b7a22
--- /dev/null
+++ b/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageTemplateHelper.java
@@ -0,0 +1,712 @@
+/*
+ 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.go;
+
+import org.apache.commons.lang3.math.NumberUtils;
+import org.apache.commons.text.WordUtils;
+import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.BaseFreemarkerLanguageTemplateHelper;
+import org.apache.plc4x.plugins.codegenerator.types.definitions.*;
+import org.apache.plc4x.plugins.codegenerator.types.fields.*;
+import org.apache.plc4x.plugins.codegenerator.types.references.*;
+import org.apache.plc4x.plugins.codegenerator.types.terms.*;
+
+import java.util.*;
+import java.util.function.Function;
+
+@SuppressWarnings({"unused", "WeakerAccess"})
+public class GoLanguageTemplateHelper extends BaseFreemarkerLanguageTemplateHelper {
+
+    public GoLanguageTemplateHelper(TypeDefinition thisType, String protocolName, String flavorName, Map<String, TypeDefinition> types) {
+        super(thisType, protocolName, flavorName, types);
+    }
+
+    public String fileName(String protocolName, String languageName, String languageFlavorName) {
+        return "plc4go." + String.join("", languageName.split("\\-")) + "." +
+            String.join("", protocolName.split("\\-")) + "." +
+            String.join("", languageFlavorName.split("\\-"));
+    }
+
+    public String packageName(String languageFlavorName) {
+        return String.join("", languageFlavorName.split("\\-"));
+    }
+
+    @Override
+    public String getLanguageTypeNameForField(Field field) {
+        boolean optional = field instanceof OptionalField;
+        // If the referenced type is a DataIo type, the value is of type PlcValue.
+        if(field instanceof PropertyField) {
+            PropertyField propertyField = (PropertyField) field;
+            if(propertyField.getType() instanceof ComplexTypeReference) {
+                ComplexTypeReference complexTypeReference = (ComplexTypeReference) propertyField.getType();
+                final TypeDefinition typeDefinition = getTypeDefinitions().get(complexTypeReference.getName());
+                if(typeDefinition instanceof DataIoTypeDefinition) {
+                    return "PlcValue";
+                }
+            }
+        }
+        return getLanguageTypeNameForTypeReference(((TypedField) field).getType());
+    }
+
+    @Override
+    public String getLanguageTypeNameForTypeReference(TypeReference typeReference) {
+        if(typeReference instanceof SimpleTypeReference) {
+            SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
+            switch (simpleTypeReference.getBaseType()) {
+                case BIT: {
+                    return "bool";
+                }
+                case UINT: {
+                    IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                    if (integerTypeReference.getSizeInBits() <= 8) {
+                        return "uint8";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 16) {
+                        return "uint16";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 32) {
+                        return "uint32";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 64) {
+                        return "uint64";
+                    }
+                    throw new RuntimeException("Unsupported simple type");
+                }
+                case INT: {
+                    IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                    if (integerTypeReference.getSizeInBits() <= 8) {
+                        return "int8";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 16) {
+                        return "int16";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 32) {
+                        return "int32";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 64) {
+                        return "int64";
+                    }
+                    throw new RuntimeException("Unsupported simple type");
+                }
+                case FLOAT:
+                case UFLOAT: {
+                    FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
+                    int sizeInBits = ((floatTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.FLOAT) ? 1 : 0) +
+                        floatTypeReference.getExponent() + floatTypeReference.getMantissa();
+                    if (sizeInBits <= 32) {
+                        return "float32";
+                    }
+                    if (sizeInBits <= 64) {
+                        return "float64";
+                    }
+                    throw new RuntimeException("Unsupported simple type");
+                }
+                case STRING: {
+                    return "string";
+                }
+                case TIME: {
+                    return "Time";
+                }
+                case DATE: {
+                    return "Date";
+                }
+                case DATETIME: {
+                    return "Date";
+                }
+            }
+            throw new RuntimeException("Unsupported simple type");
+        } else {
+            return ((ComplexTypeReference) typeReference).getName();
+        }
+    }
+
+    @Override
+    public String getNullValueForTypeReference(TypeReference typeReference) {
+        if(typeReference instanceof SimpleTypeReference) {
+            SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
+            switch (simpleTypeReference.getBaseType()) {
+                case BIT: {
+                    return "false";
+                }
+                case UINT: {
+                    IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                    if (integerTypeReference.getSizeInBits() <= 16) {
+                        return "0";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 32) {
+                        return "0l";
+                    }
+                    return "null";
+                }
+                case INT: {
+                    IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                    if (integerTypeReference.getSizeInBits() <= 32) {
+                        return "0";
+                    }
+                    if (integerTypeReference.getSizeInBits() <= 64) {
+                        return "0l";
+                    }
+                    return "null";
+                }
+                case FLOAT: {
+                    FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
+                    int sizeInBits = ((floatTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.FLOAT) ? 1 : 0) +
+                        floatTypeReference.getExponent() + floatTypeReference.getMantissa();
+                    if (sizeInBits <= 32) {
+                        return "0.0f";
+                    }
+                    if (sizeInBits <= 64) {
+                        return "0.0";
+                    }
+                    return "null";
+                }
+                case STRING: {
+                    return "null";
+                }
+            }
+            return "Hurz";
+        } else {
+            return "null";
+        }
+    }
+
+    public int getNumBits(SimpleTypeReference simpleTypeReference) {
+        switch (simpleTypeReference.getBaseType()) {
+            case BIT: {
+                return 1;
+            }
+            case UINT:
+            case INT: {
+                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                return integerTypeReference.getSizeInBits();
+            }
+            case FLOAT: {
+                FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
+                return floatTypeReference.getSizeInBits();
+            }
+            case STRING: {
+                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                return integerTypeReference.getSizeInBits();
+            }
+            default: {
+                return 0;
+            }
+        }
+    }
+
+    public String getReadBufferReadMethodCall(SimpleTypeReference simpleTypeReference, String valueString) {
+        switch (simpleTypeReference.getBaseType()) {
+            case BIT: {
+                return "io.readBit()";
+            }
+            case UINT: {
+                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                if (integerTypeReference.getSizeInBits() <= 4) {
+                    return "io.readUnsignedByte(" + integerTypeReference.getSizeInBits() + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 8) {
+                    return "io.readUnsignedShort(" + integerTypeReference.getSizeInBits() + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 16) {
+                    return "io.readUnsignedInt(" + integerTypeReference.getSizeInBits() + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 32) {
+                    return "io.readUnsignedLong(" + integerTypeReference.getSizeInBits() + ")";
+                }
+                return "io.readUnsignedBigInteger(" + integerTypeReference.getSizeInBits() + ")";
+            }
+            case INT: {
+                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                if (integerTypeReference.getSizeInBits() <= 8) {
+                    return "io.readByte(" + integerTypeReference.getSizeInBits() + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 16) {
+                    return "io.readShort(" + integerTypeReference.getSizeInBits() + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 32) {
+                    return "io.readInt(" + integerTypeReference.getSizeInBits() + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 64) {
+                    return "io.readLong(" + integerTypeReference.getSizeInBits() + ")";
+                }
+                return "io.readBigInteger(" + integerTypeReference.getSizeInBits() + ")";
+            }
+            case FLOAT: {
+                FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
+                String type = (floatTypeReference.getSizeInBits() <= 32) ? "Float" : "Double";
+                String typeCast = (floatTypeReference.getSizeInBits() <= 32) ? "float" : "double";
+                String defaultNull = (floatTypeReference.getSizeInBits() <= 32) ? "0.0f" : "0.0";
+                StringBuilder sb = new StringBuilder("((Supplier<").append(type).append(">) (() -> {");
+                sb.append("\n            return (").append(typeCast).append(") toFloat(io, ").append(
+                    (floatTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.FLOAT) ? "true" : "false")
+                    .append(", ").append(floatTypeReference.getExponent()).append(", ")
+                    .append(floatTypeReference.getMantissa()).append(");");
+                sb.append("\n        })).get()");
+                return sb.toString();
+            }
+            case STRING: {
+                StringTypeReference stringTypeReference = (StringTypeReference) simpleTypeReference;
+                return "io.readString(" + stringTypeReference.getSizeInBits() + ", \"" +
+                    stringTypeReference.getEncoding() + "\")";
+            }
+        }
+        return "Hurz";
+    }
+
+    @Override
+    public String getWriteBufferWriteMethodCall(SimpleTypeReference simpleTypeReference, String fieldName) {
+        switch (simpleTypeReference.getBaseType()) {
+            case BIT: {
+                return "io.writeBit((boolean) " + fieldName + ")";
+            }
+            case UINT: {
+                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                if (integerTypeReference.getSizeInBits() <= 4) {
+                    return "io.writeUnsignedByte(" + integerTypeReference.getSizeInBits() + ", ((Number) " + fieldName + ").byteValue())";
+                }
+                if (integerTypeReference.getSizeInBits() <= 8) {
+                    return "io.writeUnsignedShort(" + integerTypeReference.getSizeInBits() + ", ((Number) " + fieldName + ").shortValue())";
+                }
+                if (integerTypeReference.getSizeInBits() <= 16) {
+                    return "io.writeUnsignedInt(" + integerTypeReference.getSizeInBits() + ", ((Number) " + fieldName + ").intValue())";
+                }
+                if (integerTypeReference.getSizeInBits() <= 32) {
+                    return "io.writeUnsignedLong(" + integerTypeReference.getSizeInBits() + ", ((Number) " + fieldName + ").longValue())";
+                }
+                return "io.writeUnsignedBigInteger(" + integerTypeReference.getSizeInBits() + ", (BigInteger) " + fieldName + ")";
+            }
+            case INT: {
+                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                if (integerTypeReference.getSizeInBits() <= 8) {
+                    return "io.writeByte(" + integerTypeReference.getSizeInBits() + ", ((Number) " + fieldName + ").byteValue())";
+                }
+                if (integerTypeReference.getSizeInBits() <= 16) {
+                    return "io.writeShort(" + integerTypeReference.getSizeInBits() + ", ((Number) " + fieldName + ").shortValue())";
+                }
+                if (integerTypeReference.getSizeInBits() <= 32) {
+                    return "io.writeInt(" + integerTypeReference.getSizeInBits() + ", ((Number) " + fieldName + ").intValue())";
+                }
+                if (integerTypeReference.getSizeInBits() <= 64) {
+                    return "io.writeLong(" + integerTypeReference.getSizeInBits() + ", ((Number) " + fieldName + ").longValue())";
+                }
+                return "io.writeBigInteger(" + integerTypeReference.getSizeInBits() + ", BigInteger.valueOf( " + fieldName + "))";
+            }
+            case FLOAT:
+            case UFLOAT: {
+                FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
+                StringBuilder sb = new StringBuilder();
+                if(simpleTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.FLOAT) {
+                    sb.append("\n        boolean negative = value < 0;");
+                    sb.append("\n        io.writeBit(negative);");
+                }
+                sb.append("\n        final int exponent = Math.getExponent(value);");
+                sb.append("\n        final double mantissa = value / Math.pow(2, exponent);");
+                sb.append("\n        io.writeInt(").append(floatTypeReference.getExponent()).append(", exponent);");
+                sb.append("\n        io.writeDouble(").append(floatTypeReference.getMantissa()).append(", mantissa)");
+                return sb.toString().substring(9);
+            }
+            case STRING: {
+                StringTypeReference stringTypeReference = (StringTypeReference) simpleTypeReference;
+                return "io.writeString(" + stringTypeReference.getSizeInBits() + ", \"" +
+                    stringTypeReference.getEncoding() + "\", (String) " + fieldName + ")";
+            }
+        }
+        return "Hurz";
+    }
+
+    public String getReservedValue(ReservedField reservedField) {
+        final String languageTypeName = getLanguageTypeNameForTypeReference(reservedField.getType());
+        if("BigInteger".equals(languageTypeName)) {
+            return "BigInteger.valueOf(" + reservedField.getReferenceValue() + ")";
+        } else {
+            return "(" + languageTypeName + ") " + reservedField.getReferenceValue();
+        }
+    }
+
+    public String toParseExpression(TypedField field, Term term, Argument[] parserArguments) {
+        return toExpression(field, term, term1 -> toVariableParseExpression(field, term1, parserArguments));
+    }
+
+    public String toSerializationExpression(TypedField field, Term term, Argument[] parserArguments) {
+        return toExpression(field, term, term1 -> toVariableSerializationExpression(field, term1, parserArguments));
+    }
+
+    private String toExpression(TypedField field, Term term, Function<Term, String> variableExpressionGenerator) {
+        if(term == null) {
+            return "";
+        }
+        if(term instanceof Literal) {
+            if(term instanceof NullLiteral) {
+                return "null";
+            } else if(term instanceof BooleanLiteral) {
+                return Boolean.toString(((BooleanLiteral) term).getValue());
+            } else if(term instanceof NumericLiteral) {
+                return ((NumericLiteral) term).getNumber().toString();
+            } else if(term instanceof StringLiteral) {
+                return "\"" + ((StringLiteral) term).getValue() + "\"";
+            } else if(term instanceof VariableLiteral) {
+                VariableLiteral variableLiteral = (VariableLiteral) term;
+                // If this literal references an Enum type, then we have to output it differently.
+                if(getTypeDefinitions().get(variableLiteral.getName()) instanceof EnumTypeDefinition) {
+                    return variableLiteral.getName() + "." + variableLiteral.getChild().getName() +
+                        ((variableLiteral.getChild().getChild() != null) ?
+                            "." + toVariableExpressionRest(variableLiteral.getChild().getChild()) : "");
+                } else {
+                    return variableExpressionGenerator.apply(term);
+                }
+            } else {
+                throw new RuntimeException("Unsupported Literal type " + term.getClass().getName());
+            }
+        } else if (term instanceof UnaryTerm) {
+            UnaryTerm ut = (UnaryTerm) term;
+            Term a = ut.getA();
+            switch(ut.getOperation()) {
+                case "!":
+                    return "!(" + toExpression(field, a, variableExpressionGenerator) + ")";
+                case "-":
+                    return "-(" + toExpression(field, a, variableExpressionGenerator) + ")";
+                case "()":
+                    return "(" + toExpression(field, a, variableExpressionGenerator) + ")";
+                default:
+                    throw new RuntimeException("Unsupported unary operation type " + ut.getOperation());
+            }
+        } else if (term instanceof BinaryTerm) {
+            BinaryTerm bt = (BinaryTerm) term;
+            Term a = bt.getA();
+            Term b = bt.getB();
+            String operation = bt.getOperation();
+            switch (operation) {
+                case "^":
+                    return "Math.pow((" + toExpression(field, a, variableExpressionGenerator) + "), (" + toExpression(field, b, variableExpressionGenerator) + "))";
+                default:
+                    return "(" + toExpression(field, a, variableExpressionGenerator) + ") " + operation + " (" + toExpression(field, b, variableExpressionGenerator) + ")";
+            }
+        } else if (term instanceof TernaryTerm) {
+            TernaryTerm tt = (TernaryTerm) term;
+            if("if".equals(tt.getOperation())) {
+                Term a = tt.getA();
+                Term b = tt.getB();
+                Term c = tt.getC();
+                return "((" +  toExpression(field, a, variableExpressionGenerator) + ") ? " + toExpression(field, b, variableExpressionGenerator) + " : " + toExpression(field, c, variableExpressionGenerator) + ")";
+            } else {
+                throw new RuntimeException("Unsupported ternary operation type " + tt.getOperation());
+            }
+        } else {
+            throw new RuntimeException("Unsupported Term type " + term.getClass().getName());
+        }
+    }
+
+    private String toVariableParseExpression(TypedField field, Term term, Argument[] parserArguments) {
+        VariableLiteral vl = (VariableLiteral) term;
+        // CAST expressions are special as we need to add a ".class" to the second parameter in Java.
+        if("CAST".equals(vl.getName())) {
+            StringBuilder sb = new StringBuilder(vl.getName());
+            if((vl.getArgs() == null) || (vl.getArgs().size() != 2)) {
+                throw new RuntimeException("A CAST expression expects exactly two arguments.");
+            }
+            sb.append("(").append(toVariableParseExpression(field, vl.getArgs().get(0), parserArguments))
+                .append(", ").append(((VariableLiteral) vl.getArgs().get(1)).getName()).append(".class)");
+            return sb.toString() + ((vl.getChild() != null) ? "." + toVariableExpressionRest(vl.getChild()) : "");
+        }
+        else if("STATIC_CALL".equals(vl.getName())) {
+            StringBuilder sb = new StringBuilder();
+            if(!(vl.getArgs().get(0) instanceof StringLiteral)) {
+                throw new RuntimeException("Expecting the first argument of a 'STATIC_CALL' to be a StringLiteral");
+            }
+            // Get the class and method name
+            String methodName = ((StringLiteral) vl.getArgs().get(0)).getValue();
+            // Cut off the double-quptes
+            methodName = methodName.substring(1, methodName.length() - 1);
+            sb.append(methodName).append("(");
+            for(int i = 1; i < vl.getArgs().size(); i++) {
+                Term arg = vl.getArgs().get(i);
+                if(i > 1) {
+                    sb.append(", ");
+                }
+                if(arg instanceof VariableLiteral) {
+                    VariableLiteral va = (VariableLiteral) arg;
+                    // "io" is the default name of the reader argument which is always available.
+                    boolean isParserArg = "io".equals(va.getName());
+                    boolean isTypeArg = "_type".equals(va.getName());
+                    if(!isParserArg && !isTypeArg && parserArguments != null) {
+                        for (Argument parserArgument : parserArguments) {
+                            if (parserArgument.getName().equals(va.getName())) {
+                                isParserArg = true;
+                                break;
+                            }
+                        }
+                    }
+                    if(isParserArg) {
+                        sb.append(va.getName() + ((va.getChild() != null) ? "." + toVariableExpressionRest(va.getChild()) : ""));
+                    }
+                    // We have to manually evaluate the type information at code-generation time.
+                    else if(isTypeArg) {
+                        String part = va.getChild().getName();
+                        switch (part) {
+                            case "name":
+                                sb.append("\"").append(field.getTypeName()).append("\"");
+                                break;
+                            case "length":
+                                sb.append("\"").append(((SimpleTypeReference) field).getSizeInBits()).append("\"");
+                                break;
+                            case "encoding":
+                                String encoding = ((StringTypeReference) field.getType()).getEncoding();
+                                // Cut off the single quotes.
+                                encoding = encoding.substring(1, encoding.length() - 1);
+                                sb.append("\"").append(encoding).append("\"");
+                                break;
+                        }
+                    } else {
+                        sb.append(toVariableParseExpression(field, va, null));
+                    }
+                } else if(arg instanceof StringLiteral) {
+                    sb.append(((StringLiteral) arg).getValue());
+                }
+            }
+            sb.append(")");
+            return sb.toString();
+        }
+        // All uppercase names are not fields, but utility methods.
+        else if(vl.getName().equals(vl.getName().toUpperCase())) {
+            StringBuilder sb = new StringBuilder(vl.getName());
+            if(vl.getArgs() != null) {
+                sb.append("(");
+                boolean firstArg = true;
+                for(Term arg : vl.getArgs()) {
+                    if(!firstArg) {
+                        sb.append(", ");
+                    }
+                    sb.append(toParseExpression(field, arg, parserArguments));
+                    firstArg = false;
+                }
+                sb.append(")");
+            }
+            if(vl.getIndex() != VariableLiteral.NO_INDEX) {
+                sb.append("[").append(vl.getIndex()).append("]");
+            }
+            return sb.toString() + ((vl.getChild() != null) ? "." + toVariableExpressionRest(vl.getChild()) : "");
+        }
+        return vl.getName() + ((vl.getChild() != null) ? "." + toVariableExpressionRest(vl.getChild()) : "");
+    }
+
+    private String toVariableSerializationExpression(TypedField field, Term term, Argument[] serialzerArguments) {
+        VariableLiteral vl = (VariableLiteral) term;
+        if("STATIC_CALL".equals(vl.getName())) {
+            StringBuilder sb = new StringBuilder();
+            if(!(vl.getArgs().get(0) instanceof StringLiteral)) {
+                throw new RuntimeException("Expecting the first argument of a 'STATIC_CALL' to be a StringLiteral");
+            }
+            String methodName = ((StringLiteral) vl.getArgs().get(0)).getValue();
+            methodName = methodName.substring(1, methodName.length() - 1);
+            sb.append(methodName).append("(");
+            for(int i = 1; i < vl.getArgs().size(); i++) {
+                Term arg = vl.getArgs().get(i);
+                if(i > 1) {
+                    sb.append(", ");
+                }
+                if(arg instanceof VariableLiteral) {
+                    VariableLiteral va = (VariableLiteral) arg;
+                    // "io" and "_value" are always available in every parser.
+                    boolean isSerializerArg = "io".equals(va.getName()) || "_value".equals(va.getName()) || "element".equals(va.getName());
+                    boolean isTypeArg = "_type".equals(va.getName());
+                    if(!isSerializerArg && !isTypeArg && serialzerArguments != null) {
+                        for (Argument serializerArgument : serialzerArguments) {
+                            if (serializerArgument.getName().equals(va.getName())) {
+                                isSerializerArg = true;
+                                break;
+                            }
+                        }
+                    }
+                    if(isSerializerArg) {
+                        sb.append(va.getName() + ((va.getChild() != null) ? "." + toVariableExpressionRest(va.getChild()) : ""));
+                    } else if(isTypeArg) {
+                        String part = va.getChild().getName();
+                        switch (part) {
+                            case "name":
+                                sb.append("\"").append(field.getTypeName()).append("\"");
+                                break;
+                            case "length":
+                                sb.append("\"").append(((SimpleTypeReference) field).getSizeInBits()).append("\"");
+                                break;
+                            case "encoding":
+                                String encoding = ((StringTypeReference) field.getType()).getEncoding();
+                                // Cut off the single quotes.
+                                encoding = encoding.substring(1, encoding.length() - 1);
+                                sb.append("\"").append(encoding).append("\"");
+                                break;
+                        }
+                    } else {
+                        sb.append(toVariableSerializationExpression(field, va, null));
+                    }
+                } else if(arg instanceof StringLiteral) {
+                    sb.append(((StringLiteral) arg).getValue());
+                }
+            }
+            sb.append(")");
+            return sb.toString();
+        }
+        // All uppercase names are not fields, but utility methods.
+        else if(vl.getName().equals(vl.getName().toUpperCase())) {
+            StringBuilder sb = new StringBuilder(vl.getName());
+            if(vl.getArgs() != null) {
+                sb.append("(");
+                boolean firstArg = true;
+                for(Term arg : vl.getArgs()) {
+                    if(!firstArg) {
+                        sb.append(", ");
+                    }
+
+                    if(arg instanceof VariableLiteral) {
+                        VariableLiteral va = (VariableLiteral) arg;
+                        boolean isSerializerArg = "io".equals(va.getName());
+                        boolean isTypeArg = "_type".equals(va.getName());
+                        if(!isSerializerArg && !isTypeArg && serialzerArguments != null) {
+                            for (Argument serializerArgument : serialzerArguments) {
+                                if (serializerArgument.getName().equals(va.getName())) {
+                                    isSerializerArg = true;
+                                    break;
+                                }
+                            }
+                        }
+                        if(isSerializerArg) {
+                            sb.append(va.getName() + ((va.getChild() != null) ? "." + toVariableExpressionRest(va.getChild()) : ""));
+                        } else if(isTypeArg) {
+                            String part = va.getChild().getName();
+                            switch (part) {
+                                case "name":
+                                    sb.append("\"").append(field.getTypeName()).append("\"");
+                                    break;
+                                case "length":
+                                    sb.append("\"").append(((SimpleTypeReference) field).getSizeInBits()).append("\"");
+                                    break;
+                                case "encoding":
+                                    String encoding = ((StringTypeReference) field.getType()).getEncoding();
+                                    // Cut off the single quotes.
+                                    encoding = encoding.substring(1, encoding.length() - 1);
+                                    sb.append("\"").append(encoding).append("\"");
+                                    break;
+                            }
+                        } else {
+                            sb.append(toVariableSerializationExpression(field, va, null));
+                        }
+                    } else if(arg instanceof StringLiteral) {
+                        sb.append(((StringLiteral) arg).getValue());
+                    }
+                    firstArg = false;
+                }
+                sb.append(")");
+            }
+            return sb.toString();
+        }
+        // The synthetic checksumRawData is a local field and should not be accessed as bean property.
+        boolean isSerializerArg = "checksumRawData".equals(vl.getName()) || "_value".equals(vl.getName()) || "element".equals(vl.getName());
+        boolean isTypeArg = "_type".equals(vl.getName());
+        if(!isSerializerArg && !isTypeArg && serialzerArguments != null) {
+            for (Argument serializerArgument : serialzerArguments) {
+                if (serializerArgument.getName().equals(vl.getName())) {
+                    isSerializerArg = true;
+                    break;
+                }
+            }
+        }
+        if(isSerializerArg) {
+            return vl.getName() + ((vl.getChild() != null) ? "." + toVariableExpressionRest(vl.getChild()) : "");
+        } else if(isTypeArg) {
+            String part = vl.getChild().getName();
+            switch (part) {
+                case "name":
+                    return"\"" + field.getTypeName() + "\"";
+                case "length":
+                    return"\"" + ((SimpleTypeReference) field).getSizeInBits() + "\"";
+                case "encoding":
+                    String encoding = ((StringTypeReference) field.getType()).getEncoding();
+                    // Cut off the single quotes.
+                    encoding = encoding.substring(1, encoding.length() - 1);
+                    return"\"" + encoding + "\"";
+                default:
+                    return "";
+            }
+        } else {
+            return "_value." + toVariableExpressionRest(vl);
+        }
+    }
+
+    private String toVariableExpressionRest(VariableLiteral vl) {
+        return "get" + WordUtils.capitalize(vl.getName()) + "()" + ((vl.isIndexed() ? "[" + vl.getIndex() + "]" : "") +
+            ((vl.getChild() != null) ? "." + toVariableExpressionRest(vl.getChild()) : ""));
+    }
+
+    public String getSizeInBits(ComplexTypeDefinition complexTypeDefinition, Argument[] parserArguments) {
+        int sizeInBits = 0;
+        StringBuilder sb = new StringBuilder("");
+        for (Field field : complexTypeDefinition.getFields()) {
+            if(field instanceof ArrayField) {
+                ArrayField arrayField = (ArrayField) field;
+                final SimpleTypeReference type = (SimpleTypeReference) arrayField.getType();
+                switch (arrayField.getLoopType()) {
+                    case COUNT:
+                        sb.append("(").append(toSerializationExpression(null, arrayField.getLoopExpression(), parserArguments)).append(" * ").append(type.getSizeInBits()).append(") + ");
+                        break;
+                    case LENGTH:
+                        sb.append("(").append(toSerializationExpression(null, arrayField.getLoopExpression(), parserArguments)).append(" * 8) + ");
+                        break;
+                    case TERMINATED:
+                        // No terminated.
+                        break;
+                }
+            } else if(field instanceof TypedField) {
+                TypedField typedField = (TypedField) field;
+                final TypeReference type = typedField.getType();
+                if(field instanceof ManualField) {
+                    ManualField manualField = (ManualField) field;
+                    sb.append("(").append(toSerializationExpression(null, manualField.getLengthExpression(), parserArguments)).append(") + ");
+                }
+                else if(type instanceof SimpleTypeReference) {
+                    SimpleTypeReference simpleTypeReference = (SimpleTypeReference) type;
+                    sizeInBits += simpleTypeReference.getSizeInBits();
+                } else {
+                    // No ComplexTypeReference supported.
+                }
+            }
+        }
+        return sb.toString() + sizeInBits;
+    }
+
+    public String escapeValue(TypeReference typeReference, String valueString) {
+        if(valueString == null) {
+            return null;
+        }
+        if(typeReference instanceof SimpleTypeReference) {
+            SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
+            switch (simpleTypeReference.getBaseType()) {
+                case UINT:
+                case INT:
+                    // If it's a one character string and is numeric, output it as char.
+                    if(!NumberUtils.isParsable(valueString) && (valueString.length() == 1)) {
+                        return "'" + valueString + "'";
+                    }
+                    break;
+                case STRING:
+                    return "\"" + valueString + "\"";
+            }
+        }
+        return valueString;
+    }
+
+}
diff --git a/plc4j/examples/hello-connectivity-mqtt/mqtt-connector.yml b/build-utils/language-go/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.language.LanguageOutput
similarity index 56%
copy from plc4j/examples/hello-connectivity-mqtt/mqtt-connector.yml
copy to build-utils/language-go/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.language.LanguageOutput
index a0b1c15..44af1c3 100644
--- a/plc4j/examples/hello-connectivity-mqtt/mqtt-connector.yml
+++ b/build-utils/language-go/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.language.LanguageOutput
@@ -1,4 +1,4 @@
-# ----------------------------------------------------------------------------
+#
 # 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
@@ -7,7 +7,7 @@
 # "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
+#     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
@@ -15,21 +15,5 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-# ----------------------------------------------------------------------------
----
-mqtt:
-  topic-name: plc4x/test-topic
-  server-host: test.mosquitto.org
-  server-port: 1883
-plc:
-  connection: test:plc4x-example-mqtt
-  addresses:
-    - name: intParam
-      address: RANDOM/foo:INTEGER
-      size: 1
-      type: java.lang.Integer
-    - name: intParam2
-      address: RANDOM/bar:INTEGER
-      size: 1
-      type: java.lang.Integer
-polling-interval: 2000
+#
+org.apache.plc4x.language.go.GoLanguageOutput
diff --git a/build-utils/language-go/src/main/resources/templates/go/data-io-template.ftlh b/build-utils/language-go/src/main/resources/templates/go/data-io-template.ftlh
new file mode 100644
index 0000000..7c65394
--- /dev/null
+++ b/build-utils/language-go/src/main/resources/templates/go/data-io-template.ftlh
@@ -0,0 +1,312 @@
+<#--
+  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.
+-->
+<#-- Prevent freemarker from escaping stuff -->
+<#outputformat "undefined">
+<#-- Declare the name and type of variables passed in to the template -->
+<#-- @ftlvariable name="languageName" type="java.lang.String" -->
+<#-- @ftlvariable name="protocolName" type="java.lang.String" -->
+<#-- @ftlvariable name="outputFlavor" type="java.lang.String" -->
+<#-- @ftlvariable name="helper" type="org.apache.plc4x.language.go.GoLanguageTemplateHelper" -->
+<#-- @ftlvariable name="type" type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition" -->
+<#-- Declare the name and type of variables declared locally inside the template -->
+<#-- @ftlvariable name="arrayField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ArrayField" -->
+<#-- @ftlvariable name="checksumField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ChecksumField" -->
+<#-- @ftlvariable name="constField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ConstField" -->
+<#-- @ftlvariable name="discriminatorField" type="org.apache.plc4x.plugins.codegenerator.types.fields.DiscriminatorField" -->
+<#-- @ftlvariable name="enumField" type="org.apache.plc4x.plugins.codegenerator.types.fields.EnumField" -->
+<#-- @ftlvariable name="implicitField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ImplicitField" -->
+<#-- @ftlvariable name="manualArrayField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ManualArrayField" -->
+<#-- @ftlvariable name="manualField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ManualField" -->
+<#-- @ftlvariable name="optionalField" type="org.apache.plc4x.plugins.codegenerator.types.fields.OptionalField" -->
+<#-- @ftlvariable name="paddingField" type="org.apache.plc4x.plugins.codegenerator.types.fields.PaddingField" -->
+<#-- @ftlvariable name="reservedField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ReservedField" -->
+<#-- @ftlvariable name="simpleField" type="org.apache.plc4x.plugins.codegenerator.types.fields.SimpleField" -->
+<#-- @ftlvariable name="switchField" type="org.apache.plc4x.plugins.codegenerator.types.fields.SwitchField" -->
+<#-- @ftlvariable name="virtualField" type="org.apache.plc4x.plugins.codegenerator.types.fields.VirtualField" -->
+<#-- @ftlvariable name="simpleTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.SimpleTypeReference" -->
+<#-- @ftlvariable name="complexTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.ComplexTypeReference" -->
+${helper.packageName(protocolName, languageName, outputFlavor)?replace(".", "/")}/io/${type.name}IO.java
+/*
+  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 ${helper.packageName(protocolName, languageName, outputFlavor)}.io;
+
+import static org.apache.plc4x.java.spi.generation.StaticHelper.*;
+
+import org.apache.plc4x.java.api.model.PlcField;
+import org.apache.plc4x.java.api.value.*;
+import org.apache.plc4x.java.spi.generation.EvaluationHelper;
+import org.apache.plc4x.java.spi.generation.ParseException;
+import org.apache.plc4x.java.spi.generation.ReadBuffer;
+import org.apache.plc4x.java.spi.generation.WriteBuffer;
+import ${helper.packageName(protocolName, languageName, outputFlavor)}.*;
+import ${helper.packageName(protocolName, languageName, outputFlavor)}.types.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.math.BigInteger;
+import java.time.*;
+import java.util.*;
+import java.util.function.Supplier;
+
+public class ${type.name}IO {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(${type.name}IO.class);
+
+    public static PlcValue staticParse(ReadBuffer io<#if type.parserArguments?has_content>, <#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type, false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) throws ParseException {
+        <#list type.switchField.cases as case><#if case.discriminatorValues?has_content>if(<#list case.discriminatorValues as discriminatorValue>EvaluationHelper.equals(${helper.toParseExpression(null, type.switchField.discriminatorExpressions[discriminatorValue?index], type.parserArguments)}, ${discriminatorValue})<#sep> && </#sep></#list>) </#if>{ // ${case.name}
+            <#assign skipReturn=false>
+            <#list case.fields as field>
+                <#switch field.typeName>
+                    <#case "array">
+
+            // Array field (${field.name})
+            <#-- Only update curPos if the length expression uses it -->
+                        <#if field.loopExpression.contains("curPos")>
+            curPos = io.getPos() - startPos;
+                        </#if>
+            <#-- If this is a count array, we can directly initialize an array with the given size -->
+                        <#if helper.isCountArrayField(field)>
+            // Count array
+            if(${helper.toParseExpression(field, field.loopExpression, type.parserArguments)} > Integer.MAX_VALUE) {
+                throw new ParseException("Array count of " + (${helper.toParseExpression(field, field.loopExpression, type.parserArguments)}) + " exceeds the maximum allowed count of " + Integer.MAX_VALUE);
+            }
+            List<Plc${case.name}> ${field.name};
+            {
+                int itemCount = (int) ${helper.toParseExpression(field, field.loopExpression, type.parserArguments)};
+                ${field.name} = new LinkedList<>();
+                for(int curItem = 0; curItem < itemCount; curItem++) {
+                    ${field.name}.add(new Plc${case.name}((${helper.getNonPrimitiveLanguageTypeNameForField(field)}) <#if helper.isSimpleTypeReference(field.type)>${helper.getReadBufferReadMethodCall(field.type)})<#else>${field.type.name}IO.staticParse(io<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(field.type, parserArgument?index), true)}) (${helper.toParseExpression(field, parserArgument, type [...]
+                }
+            }
+            <#-- 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 helper.isLengthArrayField(field)>
+            // Length array
+            int _${field.name}Length = ${helper.toParseExpression(field, field.loopExpression, type.parserArguments)};
+            List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}> _${field.name}List = new LinkedList<>();
+            int ${field.name}EndPos = io.getPos() + _${field.name}Length;
+            while(io.getPos() < ${field.name}EndPos) {
+                _${field.name}List.add(<#if helper.isSimpleTypeReference(field.type)>${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name}IO.staticParse(io<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(field.type, parserArgument?index), true)}) (${helper.toParseExpression(field, parserArgument, type.parserArguments)})<#sep>, </#sep></#list></#if>)</#if>);
+                <#-- After parsing, update the current position, but only if it's needed -->
+                                <#if field.loopExpression.contains("curPos")>
+                curPos = io.getPos() - startPos;
+                                </#if>
+            }
+            <#-- A terminated array keeps on reading data as long as the termination expression evaluates to false -->
+                            <#elseif helper.isTerminatedArrayField(field)>
+            // Terminated array
+            List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}> _${field.name}List = new LinkedList<>();
+            while(!((boolean) (${helper.toParseExpression(field, field.loopExpression, type.parserArguments)}))) {
+                _${field.name}List.add(<#if helper.isSimpleTypeReference(field.type)>${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name}IO.staticParse(io<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(field.type, parserArgument?index), true)}) (${helper.toParseExpression(field, parserArgument, type.parserArguments)})<#sep>, </#sep></#list></#if>)</#if>);
+
+                <#-- After parsing, update the current position, but only if it's needed -->
+                                <#if field.loopExpression.contains("curPos")>
+                curPos = io.getPos() - startPos;
+                                </#if>
+            }
+                            </#if>
+            <#--
+                Convert the list into an array. However if the array is of a primitive
+                type we have to iterate over it's elements and explicitly cast them.
+                Otherwise a simple toArray call is fine.
+            -->
+                            <#if helper.isSimpleTypeReference(field.type)>
+            ${helper.getNonPrimitiveLanguageTypeNameForField(field)}[] ${field.name} = new ${helper.getNonPrimitiveLanguageTypeNameForField(field)}[_${field.name}List.size()];
+            for(int i = 0; i < _${field.name}List.size(); i++) {
+                ${field.name}[i] = (${helper.getNonPrimitiveLanguageTypeNameForField(field)}) _${field.name}List.get(i);
+            }
+                            <#else>
+            ${helper.getNonPrimitiveLanguageTypeNameForField(field)}[] ${field.name} = _${field.name}List.toArray(new ${helper.getNonPrimitiveLanguageTypeNameForField(field)}[0]);
+                            </#if>
+                        </#if>
+                    <#break>
+                    <#case "const">
+
+            // Const Field (${field.name})
+            ${helper.getNonPrimitiveLanguageTypeNameForField(field)} ${field.name} = ${helper.getReadBufferReadMethodCall(field.type)};
+            if(${field.name} != ${type.name}.${field.name?upper_case}) {
+                throw new ParseException("Expected constant value " + ${type.name}.${field.name?upper_case} + " but got " + ${field.name});
+            }
+                    <#break>
+                    <#case "enum">
+
+            // Enum field (${field.name})
+            ${helper.getNonPrimitiveLanguageTypeNameForField(field)} ${field.name} = ${helper.getNonPrimitiveLanguageTypeNameForField(field)}.valueOf(${helper.getReadBufferReadMethodCall(helper.getEnumBaseTypeReference(field.type))});
+                    <#break>
+                    <#case "manual">
+
+            // Manual Field (${field.name})
+            ${helper.getLanguageTypeNameForField(field)} ${field.name} = (${helper.getLanguageTypeNameForField(field)}) (${helper.toParseExpression(field, field.parseExpression, type.parserArguments)});
+                        <#-- If a manual field is detected, the value returned by this is instantly treated as the value -->
+                        <#switch case.name>
+                            <#case "Time">
+            return new PlcTime(${field.name});
+                            <#break>
+                            <#case "Date">
+            return new PlcDate(${field.name});
+                            <#break>
+                            <#case "DateTime">
+            return new PlcDateTime(${field.name});
+                            <#break>
+                            <#case "Struct">
+            return new PlcStruct(${field.name});
+                            <#break>
+                            <#case "String">
+            return new PlcString(${field.name});
+                            <#break>
+                            <#default>
+            return new Plc${case.name}(${field.name});
+                        </#switch>
+                        <#-- As we returned early, skip outputting a return at the end -->
+                        <#assign skipReturn=true>
+                    <#break>
+                    <#case "reserved">
+
+            // Reserved Field (Compartmentalized so the "reserved" variable can't leak)
+            {
+                ${helper.getLanguageTypeNameForField(field)} reserved = ${helper.getReadBufferReadMethodCall(field.type)};
+                if(reserved != ${helper.getReservedValue(field)}) {
+                    LOGGER.info("Expected constant value " + ${field.referenceValue} + " but got " + reserved + " for reserved field.");
+                }
+            }
+                    <#break>
+                    <#case "simple">
+
+            // Simple Field (${field.name})
+            ${helper.getNonPrimitiveLanguageTypeNameForField(field)} ${field.name} = <#if helper.isSimpleTypeReference(field.type)>${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name}IO.staticParse(io<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(field.type, parserArgument?index), true)}) (${helper.toParseExpression(field, parserArgument, type.parserArguments)})<#sep>, </#sep [...]
+                    <#break>
+                </#switch>
+            </#list>
+            <#if case.name == "Struct">
+            Map<String, PlcValue> _map = new HashMap<>();
+                <#list case.fields as field>
+            _map.put("${field.name}", PlcValues.of(${field.name}));
+                </#list>
+            </#if>
+            <#if !skipReturn>
+                <#switch case.name>
+                    <#case "Time">
+            return new PlcTime(LocalTime.of((int) hours, (int) minutes, (int) seconds));
+                    <#break>
+                    <#case "Date">
+            return new PlcDate(LocalDate.of((int) year, (int) month, (int) day));
+                    <#break>
+                    <#case "DateTime">
+            return new PlcDateTime(LocalDateTime.of((int) year, (int) month, (int) day, (int) hours, (int) minutes, (int) seconds));
+                    <#break>
+                    <#case "Struct">
+            return new PlcStruct(_map);
+                    <#break>
+                    <#case "List">
+            return new PlcList(value);
+                    <#break>
+            <#-- Disable this for now as Strings will only be parsed as manual fields -->
+                    <#case "String">
+            //return new PlcString(_map);
+                    <#break>
+                    <#default>
+                    <#if helper.isCountArrayField(case.fields[0])>
+            return new PlcList(value);
+                    <#else>
+            return new Plc${case.name}(value);
+                    </#if>
+                </#switch>
+            </#if>
+        }<#sep> else </#sep></#list>
+        return null;
+    }
+
+<#if outputFlavor != "passive">
+    public static WriteBuffer staticSerialize(PlcValue _value<#if type.parserArguments?has_content>, <#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type, false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) throws ParseException {
+        return staticSerialize(_value<#if type.parserArguments?has_content>, <#list type.parserArguments as parserArgument>${parserArgument.name}<#sep>, </#sep></#list></#if>, false);
+    }
+
+    public static WriteBuffer staticSerialize(PlcValue _value<#if type.parserArguments?has_content>, <#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type, false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>, boolean littleEndian) throws ParseException {
+        <#list type.switchField.cases as case><#if case.discriminatorValues?has_content>if(<#list case.discriminatorValues as discriminatorValue>EvaluationHelper.equals(${helper.toParseExpression(null, type.switchField.discriminatorExpressions[discriminatorValue?index], type.parserArguments)}, ${discriminatorValue})<#sep> && </#sep></#list>) </#if>{ // ${case.name}
+            WriteBuffer io = new WriteBuffer(${helper.getSizeInBits(case, type.parserArguments)} / 8, littleEndian);
+
+            <#list case.fields as field>
+                <#switch field.typeName>
+                    <#case "array">
+                    <#break>
+                    <#case "const">
+            // Const Field (${field.name})
+            ${helper.getWriteBufferWriteMethodCall(field.type, field.referenceValue)};
+                    <#break>
+                    <#case "enum">
+            // Enum field (${field.name})
+            ${helper.getLanguageTypeNameForField(field)} ${field.name} = (${helper.getLanguageTypeNameForField(field)}) _value.get${field.name?cap_first}();
+            ${helper.getWriteBufferWriteMethodCall(helper.getEnumBaseTypeReference(field.type), "(" + field.name + ".getValue())")};
+                    <#break>
+                    <#case "manual">
+            // Manual Field (${field.name})
+            ${helper.toSerializationExpression(field, field.serializeExpression, type.parserArguments)};
+                    <#break>
+                    <#case "reserved">
+            // Reserved Field
+            ${helper.getWriteBufferWriteMethodCall(field.type, helper.getReservedValue(field))};
+                    <#break>
+                    <#case "simple">
+            // Simple Field (${field.name})
+                        <#if case.name == "Struct">
+            ${helper.getLanguageTypeNameForField(field)} ${field.name} = (${helper.getLanguageTypeNameForField(field)}) _value.getStruct().get("${field.name}").get${helper.getLanguageTypeNameForField(field)?cap_first}();
+                        <#else>
+                            <#if field.name == "value">
+            ${helper.getLanguageTypeNameForField(field)} ${field.name} = (${helper.getLanguageTypeNameForField(field)}) _value.get${helper.getLanguageTypeNameForField(field)?cap_first}();
+                            <#else>
+                                <#-- Just for now -->
+            ${helper.getLanguageTypeNameForField(field)} ${field.name} = ${helper.getNullValueForTypeReference(field.type)};
+                            </#if>
+                        </#if>
+                        <#if helper.isSimpleTypeReference(field.type)>
+            ${helper.getWriteBufferWriteMethodCall(field.type, "(" + field.name + ")")};
+                        <#else>
+            ${field.type.name}IO.staticSerialize(io, ${field.name});
+                        </#if>
+                    <#break>
+                </#switch>
+            </#list>
+            return io;
+        }<#sep> else </#sep></#list>
+        return null;
+    }
+</#if>
+
+}
+</#outputformat>
diff --git a/build-utils/language-go/src/main/resources/templates/go/enum-package-info-template.ftlh b/build-utils/language-go/src/main/resources/templates/go/enum-package-info-template.ftlh
new file mode 100644
index 0000000..d5a4373
--- /dev/null
+++ b/build-utils/language-go/src/main/resources/templates/go/enum-package-info-template.ftlh
@@ -0,0 +1,47 @@
+<#--
+  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.
+-->
+<#-- Prevent freemarker from escaping stuff -->
+<#outputformat "undefined">
+<#-- Declare the name and type of variables passed in to the template -->
+<#-- @ftlvariable name="languageName" type="java.lang.String" -->
+<#-- @ftlvariable name="protocolName" type="java.lang.String" -->
+<#-- @ftlvariable name="outputFlavor" type="java.lang.String" -->
+<#-- @ftlvariable name="helper" type="org.apache.plc4x.language.go.GoLanguageTemplateHelper" -->
+${helper.packageName(protocolName, languageName, outputFlavor)?replace(".", "/")}/types/package-info.java
+/*
+  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 ${helper.packageName(protocolName, languageName, outputFlavor)}.types;
+</#outputformat>
\ No newline at end of file
diff --git a/build-utils/language-go/src/main/resources/templates/go/enum-template.ftlh b/build-utils/language-go/src/main/resources/templates/go/enum-template.ftlh
new file mode 100644
index 0000000..e4e1d4c
--- /dev/null
+++ b/build-utils/language-go/src/main/resources/templates/go/enum-template.ftlh
@@ -0,0 +1,115 @@
+<#--
+<#--
+  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.
+-->
+<#-- Prevent freemarker from escaping stuff -->
+<#outputformat "undefined">
+<#-- Declare the name and type of variables passed in to the template -->
+<#-- @ftlvariable name="languageName" type="java.lang.String" -->
+<#-- @ftlvariable name="protocolName" type="java.lang.String" -->
+<#-- @ftlvariable name="outputFlavor" type="java.lang.String" -->
+<#-- @ftlvariable name="helper" type="org.apache.plc4x.language.go.GoLanguageTemplateHelper" -->
+<#-- @ftlvariable name="type" type="org.apache.plc4x.plugins.codegenerator.types.definitions.EnumTypeDefinition" -->
+${helper.packageName(protocolName, languageName, outputFlavor)?replace(".", "/")}/types/${type.name}.java
+/*
+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 ${helper.packageName(protocolName, languageName, outputFlavor)}.types;
+
+import org.apache.plc4x.java.spi.generation.Message;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum ${type.name} {
+
+<#list type.enumValues as enumValue>
+    ${enumValue.name}(<#if type.type?has_content>(${helper.getLanguageTypeNameForTypeReference(type.type, true)}) ${enumValue.value}</#if><#if type.constantNames?has_content><#if type.type?has_content>, </#if><#list type.constantNames as constantName>(${helper.getLanguageTypeNameForTypeReference(type.getConstantType(constantName), true)}) ${helper.escapeValue(type.getConstantType(constantName), enumValue.getConstant(constantName))}<#sep>, </#sep></#list></#if>)<#sep>,
+</#sep></#list>;
+
+<#if type.type?has_content>
+    private static final Logger logger = LoggerFactory.getLogger(${type.name}.class);
+
+    private static final Map<${helper.getLanguageTypeNameForTypeReference(type.type, false)}, ${type.name}> map;
+    static {
+        map = new HashMap<>();
+        for (${type.name} value : ${type.name}.values()) {
+            map.put((${helper.getLanguageTypeNameForTypeReference(type.type, true)}) value.getValue(), value);
+        }
+    }
+
+    private ${helper.getLanguageTypeNameForTypeReference(type.type, true)} value;
+</#if>
+<#if type.constantNames?has_content>
+    <#list type.constantNames as constantName>
+        private ${helper.getLanguageTypeNameForTypeReference(type.getConstantType(constantName), true)} ${constantName};
+    </#list>
+</#if>
+
+    ${type.name}(<#if type.type?has_content>${helper.getLanguageTypeNameForTypeReference(type.type, true)} value</#if><#if type.constantNames?has_content><#if type.type?has_content>, </#if><#list type.constantNames as constantName>${helper.getLanguageTypeNameForTypeReference(type.getConstantType(constantName), true)} ${constantName}<#sep>, </#sep></#list></#if>) {
+<#if type.type?has_content>        this.value = value;</#if>
+<#if type.constantNames?has_content>
+    <#list type.constantNames as constantName>
+        this.${constantName} = ${constantName};
+    </#list>
+</#if>
+    }
+
+<#if type.type?has_content>
+    public ${helper.getLanguageTypeNameForTypeReference(type.type, true)} getValue() {
+        return value;
+    }
+</#if>
+
+<#if type.constantNames?has_content>
+    <#list type.constantNames as constantName>
+    public ${helper.getLanguageTypeNameForTypeReference(type.getConstantType(constantName), true)} get${constantName?cap_first}() {
+        return ${constantName};
+    }
+
+    </#list>
+</#if>
+<#if type.type?has_content>
+    public static ${type.name} valueOf(${helper.getLanguageTypeNameForTypeReference(type.type, true)} value) {
+        if (!map.containsKey(value)) {
+            logger.error("No ${type.name} for value {}", value);
+        }
+        return map.get(value);
+    }
+</#if>
+
+}
+</#outputformat>
\ No newline at end of file
diff --git a/build-utils/language-go/src/main/resources/templates/go/pojo-template.ftlh b/build-utils/language-go/src/main/resources/templates/go/pojo-template.ftlh
new file mode 100644
index 0000000..33759dd
--- /dev/null
+++ b/build-utils/language-go/src/main/resources/templates/go/pojo-template.ftlh
@@ -0,0 +1,216 @@
+<#--
+  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.
+-->
+<#-- Prevent freemarker from escaping stuff -->
+<#outputformat "undefined">
+<#-- Declare the name and type of variables passed in to the template -->
+<#-- @ftlvariable name="languageName" type="java.lang.String" -->
+<#-- @ftlvariable name="protocolName" type="java.lang.String" -->
+<#-- @ftlvariable name="outputFlavor" type="java.lang.String" -->
+<#-- @ftlvariable name="helper" type="org.apache.plc4x.language.go.GoLanguageTemplateHelper" -->
+<#-- @ftlvariable name="type" type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition" -->
+<#-- Declare the name and type of variables declared locally inside the template -->
+<#-- @ftlvariable name="arrayField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ArrayField" -->
+<#-- @ftlvariable name="checksumField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ChecksumField" -->
+<#-- @ftlvariable name="constField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ConstField" -->
+<#-- @ftlvariable name="discriminatorField" type="org.apache.plc4x.plugins.codegenerator.types.fields.DiscriminatorField" -->
+<#-- @ftlvariable name="enumField" type="org.apache.plc4x.plugins.codegenerator.types.fields.EnumField" -->
+<#-- @ftlvariable name="implicitField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ImplicitField" -->
+<#-- @ftlvariable name="manualArrayField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ManualArrayField" -->
+<#-- @ftlvariable name="manualField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ManualField" -->
+<#-- @ftlvariable name="optionalField" type="org.apache.plc4x.plugins.codegenerator.types.fields.OptionalField" -->
+<#-- @ftlvariable name="paddingField" type="org.apache.plc4x.plugins.codegenerator.types.fields.PaddingField" -->
+<#-- @ftlvariable name="reservedField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ReservedField" -->
+<#-- @ftlvariable name="simpleField" type="org.apache.plc4x.plugins.codegenerator.types.fields.SimpleField" -->
+<#-- @ftlvariable name="switchField" type="org.apache.plc4x.plugins.codegenerator.types.fields.SwitchField" -->
+<#-- @ftlvariable name="virtualField" type="org.apache.plc4x.plugins.codegenerator.types.fields.VirtualField" -->
+<#-- @ftlvariable name="simpleTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.SimpleTypeReference" -->
+<#-- @ftlvariable name="complexTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.ComplexTypeReference" -->
+${helper.fileName(protocolName, languageName, outputFlavor)?replace(".", "/")}/${type.name}.go
+//
+// 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 ${helper.packageName(outputFlavor)}
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ${type.name} struct {
+<#-- Prpoerty fields are fields that require a property in the pojo -->
+<#if type.propertyFields?has_content>
+<#list type.propertyFields as field>
+    ${field.name} <#if field.loopType??>[]</#if>${helper.getLanguageTypeNameForField(field)}
+</#list>
+</#if>
+<#--
+    This is GO's version of inheritance
+    (Makes all properties of the following type available in this tpye)
+-->
+<#if type.parentType??>    ${type.parentType.name}</#if>
+}
+
+func (m ${type.name}) lengthInBits() uint16 {
+    var lengthInBits uint16 = <#if type.parentType??>m.${type.parentType.name}.lengthInBits()<#else>0</#if>
+    <#list type.fields as field>
+        <#switch field.typeName>
+            <#case "array">
+                <#assign arrayField = field>
+
+    // Array field
+    if len(m.${arrayField.name}) > 0 {
+                <#if helper.isSimpleTypeReference(arrayField.type)>
+                    <#assign simpleTypeReference = arrayField.type>
+        lengthInBits += ${simpleTypeReference.sizeInBits} * uint16(len(m.${arrayField.name}))
+                <#else>
+        for _, element := range m.${arrayField.name} {
+            lengthInBits += element.lengthInBits()
+        }
+                </#if>
+    }
+                <#break>
+            <#case "checksum">
+                <#assign checksumField = field>
+                <#assign simpleTypeReference = checksumField.type>
+
+    // Checksum Field (checksum)
+    lengthInBits += ${simpleTypeReference.sizeInBits}
+                <#break>
+            <#case "const">
+                <#assign constField = field>
+                <#assign simpleTypeReference = constField.type>
+
+    // Const Field (${constField.name})
+    lengthInBits += ${simpleTypeReference.sizeInBits}
+                <#break>
+            <#case "discriminator">
+                <#assign discriminatorField = field>
+                <#assign simpleTypeReference = discriminatorField.type>
+
+    // Discriminator Field (${discriminatorField.name})
+    lengthInBits += ${simpleTypeReference.sizeInBits}
+                <#break>
+            <#case "enum">
+                <#assign enumField = field>
+
+    // Enum Field (${enumField.name})
+    lengthInBits += ${helper.getEnumBaseTypeReference(enumField.type).sizeInBits}
+                <#break>
+            <#case "implicit">
+                <#assign implicitField = field>
+                <#assign simpleTypeReference = implicitField.type>
+
+    // Implicit Field (${implicitField.name})
+    lengthInBits += ${simpleTypeReference.sizeInBits}
+                <#break>
+            <#case "manualArray">
+                <#assign manualArrayField = field>
+
+    // Manual Array Field (${manualArrayField.name})
+    lengthInBits += ${helper.toParseExpression(manualArrayField, manualArrayField.lengthExpression, type.parserArguments)} * 8
+                <#break>
+            <#case "manual">
+                <#assign manualField = field>
+
+    // Manual Field (${manualField.name})
+    lengthInBits += ${helper.toParseExpression(manualField, manualField.lengthExpression, type.parserArguments)} * 8
+                <#break>
+            <#case "optional">
+                <#assign optionalField = field>
+
+    // Optional Field (${optionalField.name})
+    if m.${optionalField.name} != nil {
+                <#if helper.isSimpleTypeReference(optionalField.type)>
+                    <#assign simpleTypeReference = optionalField.type>
+        lengthInBits += ${simpleTypeReference.sizeInBits}
+                <#else>
+        lengthInBits += m.${optionalField.name}.lengthInBits()
+                </#if>
+    }
+                <#break>
+            <#case "padding">
+                <#assign paddingField = field>
+                <#assign simpleTypeReference = paddingField.type>
+
+    // Padding Field (padding)
+            <#-- We're replacing the "lastItem" with 'false' here as the item itself can't know if it is the last -->
+    _timesPadding:uint8 = uint8(${helper.toParseExpression(paddingField, paddingField.paddingCondition, type.parserArguments)?replace("lastItem", "false")})
+    for _timesPadding > 0; _timesPadding-- {
+        lengthInBits += ${simpleTypeReference.sizeInBits}
+    }
+                <#break>
+            <#case "reserved">
+                <#assign reservedField = field>
+                <#assign simpleTypeReference = reservedField.type>
+
+    // Reserved Field (reserved)
+    lengthInBits += ${simpleTypeReference.sizeInBits}
+                <#break>
+            <#case "simple">
+                <#assign simpleField = field>
+
+    // Simple field (${simpleField.name})
+                <#if helper.isSimpleTypeReference(simpleField.type)>
+                    <#assign simpleTypeReference = simpleField.type>
+    lengthInBits += ${simpleTypeReference.sizeInBits}
+                <#else>
+    lengthInBits += m.${simpleField.name}.lengthInBits()
+                </#if>
+                <#break>
+            <#case "switch">
+                <#assign switchField = field>
+
+    // Length of sub-type elements will be added by sub-type...
+                <#break>
+            <#case "virtual">
+                <#assign virtualField = field>
+
+    // A virtual field doesn't have any in- or output.
+                <#break>
+        </#switch>
+    </#list>
+
+    return lengthInBits
+}
+
+func (m ${type.name}) lengthInBytes() uint16 {
+    return m.lengthInBits() / 8
+}
+
+func (m ${type.name}) parse(io spi.ReadBuffer) {
+    // TODO: Implement ...
+}
+
+func (m ${type.name}) serialize(io spi.WriteBuffer) {
+    // TODO: Implement ...
+}
+
+</#outputformat>
\ No newline at end of file
diff --git a/build-utils/pom.xml b/build-utils/pom.xml
index a52aaed..4fe4e2e 100644
--- a/build-utils/pom.xml
+++ b/build-utils/pom.xml
@@ -38,6 +38,7 @@
     <module>protocol-base-mspec</module>
 
     <module>language-c</module>
+    <module>language-go</module>
     <module>language-java</module>
     <module>protocol-test</module>
   </modules>
diff --git a/plc4j/examples/hello-connectivity-mqtt/mqtt-connector.yml b/plc4j/examples/hello-connectivity-mqtt/mqtt-connector.yml
index a0b1c15..098f14f 100644
--- a/plc4j/examples/hello-connectivity-mqtt/mqtt-connector.yml
+++ b/plc4j/examples/hello-connectivity-mqtt/mqtt-connector.yml
@@ -1,4 +1,4 @@
-# ----------------------------------------------------------------------------
+ # ----------------------------------------------------------------------------
 # 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
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusConstants.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusConstants.go
new file mode 100644
index 0000000..4331bb0
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusConstants.go
@@ -0,0 +1,45 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusConstants struct {
+}
+
+func (m ModbusConstants) lengthInBits() uint16 {
+	var lengthInBits uint16 = 0
+
+	// Const Field (modbusTcpDefaultPort)
+	lengthInBits += 16
+
+	return lengthInBits
+}
+
+func (m ModbusConstants) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusConstants) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusConstants) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDU.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDU.go
new file mode 100644
index 0000000..58dbb4e
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDU.go
@@ -0,0 +1,50 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDU struct {
+}
+
+func (m ModbusPDU) lengthInBits() uint16 {
+	var lengthInBits uint16 = 0
+
+	// Discriminator Field (error)
+	lengthInBits += 1
+
+	// Discriminator Field (function)
+	lengthInBits += 7
+
+	// Length of sub-type elements will be added by sub-type...
+
+	return lengthInBits
+}
+
+func (m ModbusPDU) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDU) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDU) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUDiagnosticRequest.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUDiagnosticRequest.go
new file mode 100644
index 0000000..aaf833d
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUDiagnosticRequest.go
@@ -0,0 +1,51 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUDiagnosticRequest struct {
+	status     uint16
+	eventCount uint16
+	ModbusPDU
+}
+
+func (m ModbusPDUDiagnosticRequest) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Simple field (status)
+	lengthInBits += 16
+
+	// Simple field (eventCount)
+	lengthInBits += 16
+
+	return lengthInBits
+}
+
+func (m ModbusPDUDiagnosticRequest) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUDiagnosticRequest) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUDiagnosticRequest) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUError.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUError.go
new file mode 100644
index 0000000..ecc483d
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUError.go
@@ -0,0 +1,47 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUError struct {
+	exceptionCode uint8
+	ModbusPDU
+}
+
+func (m ModbusPDUError) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Simple field (exceptionCode)
+	lengthInBits += 8
+
+	return lengthInBits
+}
+
+func (m ModbusPDUError) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUError) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUError) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUGetComEventLogRequest.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUGetComEventLogRequest.go
new file mode 100644
index 0000000..6751da1
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUGetComEventLogRequest.go
@@ -0,0 +1,43 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUGetComEventLogRequest struct {
+	ModbusPDU
+}
+
+func (m ModbusPDUGetComEventLogRequest) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	return lengthInBits
+}
+
+func (m ModbusPDUGetComEventLogRequest) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUGetComEventLogRequest) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUGetComEventLogRequest) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUGetComEventLogResponse.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUGetComEventLogResponse.go
new file mode 100644
index 0000000..e5c503b
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUGetComEventLogResponse.go
@@ -0,0 +1,64 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUGetComEventLogResponse struct {
+	status       uint16
+	eventCount   uint16
+	messageCount uint16
+	events       []int8
+	ModbusPDU
+}
+
+func (m ModbusPDUGetComEventLogResponse) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Implicit Field (byteCount)
+	lengthInBits += 8
+
+	// Simple field (status)
+	lengthInBits += 16
+
+	// Simple field (eventCount)
+	lengthInBits += 16
+
+	// Simple field (messageCount)
+	lengthInBits += 16
+
+	// Array field
+	if len(m.events) > 0 {
+		lengthInBits += 8 * uint16(len(m.events))
+	}
+
+	return lengthInBits
+}
+
+func (m ModbusPDUGetComEventLogResponse) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUGetComEventLogResponse) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUGetComEventLogResponse) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterRequest.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterRequest.go
new file mode 100644
index 0000000..d038f3e
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterRequest.go
@@ -0,0 +1,55 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUMaskWriteHoldingRegisterRequest struct {
+	referenceAddress uint16
+	andMask          uint16
+	orMask           uint16
+	ModbusPDU
+}
+
+func (m ModbusPDUMaskWriteHoldingRegisterRequest) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Simple field (referenceAddress)
+	lengthInBits += 16
+
+	// Simple field (andMask)
+	lengthInBits += 16
+
+	// Simple field (orMask)
+	lengthInBits += 16
+
+	return lengthInBits
+}
+
+func (m ModbusPDUMaskWriteHoldingRegisterRequest) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUMaskWriteHoldingRegisterRequest) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUMaskWriteHoldingRegisterRequest) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterResponse.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterResponse.go
new file mode 100644
index 0000000..5c386bb
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterResponse.go
@@ -0,0 +1,55 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUMaskWriteHoldingRegisterResponse struct {
+	referenceAddress uint16
+	andMask          uint16
+	orMask           uint16
+	ModbusPDU
+}
+
+func (m ModbusPDUMaskWriteHoldingRegisterResponse) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Simple field (referenceAddress)
+	lengthInBits += 16
+
+	// Simple field (andMask)
+	lengthInBits += 16
+
+	// Simple field (orMask)
+	lengthInBits += 16
+
+	return lengthInBits
+}
+
+func (m ModbusPDUMaskWriteHoldingRegisterResponse) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUMaskWriteHoldingRegisterResponse) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUMaskWriteHoldingRegisterResponse) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadCoilsRequest.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadCoilsRequest.go
new file mode 100644
index 0000000..db57590
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadCoilsRequest.go
@@ -0,0 +1,51 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReadCoilsRequest struct {
+	startingAddress uint16
+	quantity        uint16
+	ModbusPDU
+}
+
+func (m ModbusPDUReadCoilsRequest) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Simple field (startingAddress)
+	lengthInBits += 16
+
+	// Simple field (quantity)
+	lengthInBits += 16
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReadCoilsRequest) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReadCoilsRequest) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReadCoilsRequest) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadCoilsResponse.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadCoilsResponse.go
new file mode 100644
index 0000000..40a7631
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadCoilsResponse.go
@@ -0,0 +1,52 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReadCoilsResponse struct {
+	value []int8
+	ModbusPDU
+}
+
+func (m ModbusPDUReadCoilsResponse) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Implicit Field (byteCount)
+	lengthInBits += 8
+
+	// Array field
+	if len(m.value) > 0 {
+		lengthInBits += 8 * uint16(len(m.value))
+	}
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReadCoilsResponse) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReadCoilsResponse) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReadCoilsResponse) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadDeviceIdentificationRequest.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadDeviceIdentificationRequest.go
new file mode 100644
index 0000000..232c91e
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadDeviceIdentificationRequest.go
@@ -0,0 +1,43 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReadDeviceIdentificationRequest struct {
+	ModbusPDU
+}
+
+func (m ModbusPDUReadDeviceIdentificationRequest) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReadDeviceIdentificationRequest) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReadDeviceIdentificationRequest) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReadDeviceIdentificationRequest) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadDeviceIdentificationResponse.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadDeviceIdentificationResponse.go
new file mode 100644
index 0000000..716671b
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadDeviceIdentificationResponse.go
@@ -0,0 +1,43 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReadDeviceIdentificationResponse struct {
+	ModbusPDU
+}
+
+func (m ModbusPDUReadDeviceIdentificationResponse) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReadDeviceIdentificationResponse) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReadDeviceIdentificationResponse) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReadDeviceIdentificationResponse) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadDiscreteInputsRequest.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadDiscreteInputsRequest.go
new file mode 100644
index 0000000..945e026
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadDiscreteInputsRequest.go
@@ -0,0 +1,51 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReadDiscreteInputsRequest struct {
+	startingAddress uint16
+	quantity        uint16
+	ModbusPDU
+}
+
+func (m ModbusPDUReadDiscreteInputsRequest) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Simple field (startingAddress)
+	lengthInBits += 16
+
+	// Simple field (quantity)
+	lengthInBits += 16
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReadDiscreteInputsRequest) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReadDiscreteInputsRequest) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReadDiscreteInputsRequest) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadDiscreteInputsResponse.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadDiscreteInputsResponse.go
new file mode 100644
index 0000000..54446df
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadDiscreteInputsResponse.go
@@ -0,0 +1,52 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReadDiscreteInputsResponse struct {
+	value []int8
+	ModbusPDU
+}
+
+func (m ModbusPDUReadDiscreteInputsResponse) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Implicit Field (byteCount)
+	lengthInBits += 8
+
+	// Array field
+	if len(m.value) > 0 {
+		lengthInBits += 8 * uint16(len(m.value))
+	}
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReadDiscreteInputsResponse) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReadDiscreteInputsResponse) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReadDiscreteInputsResponse) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadExceptionStatusRequest.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadExceptionStatusRequest.go
new file mode 100644
index 0000000..467005f
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadExceptionStatusRequest.go
@@ -0,0 +1,43 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReadExceptionStatusRequest struct {
+	ModbusPDU
+}
+
+func (m ModbusPDUReadExceptionStatusRequest) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReadExceptionStatusRequest) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReadExceptionStatusRequest) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReadExceptionStatusRequest) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadExceptionStatusResponse.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadExceptionStatusResponse.go
new file mode 100644
index 0000000..a881667
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadExceptionStatusResponse.go
@@ -0,0 +1,47 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReadExceptionStatusResponse struct {
+	value uint8
+	ModbusPDU
+}
+
+func (m ModbusPDUReadExceptionStatusResponse) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Simple field (value)
+	lengthInBits += 8
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReadExceptionStatusResponse) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReadExceptionStatusResponse) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReadExceptionStatusResponse) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadFifoQueueRequest.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadFifoQueueRequest.go
new file mode 100644
index 0000000..abd3074
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadFifoQueueRequest.go
@@ -0,0 +1,47 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReadFifoQueueRequest struct {
+	fifoPointerAddress uint16
+	ModbusPDU
+}
+
+func (m ModbusPDUReadFifoQueueRequest) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Simple field (fifoPointerAddress)
+	lengthInBits += 16
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReadFifoQueueRequest) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReadFifoQueueRequest) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReadFifoQueueRequest) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadFifoQueueResponse.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadFifoQueueResponse.go
new file mode 100644
index 0000000..4268d8d
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadFifoQueueResponse.go
@@ -0,0 +1,55 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReadFifoQueueResponse struct {
+	fifoValue []uint16
+	ModbusPDU
+}
+
+func (m ModbusPDUReadFifoQueueResponse) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Implicit Field (byteCount)
+	lengthInBits += 16
+
+	// Implicit Field (fifoCount)
+	lengthInBits += 16
+
+	// Array field
+	if len(m.fifoValue) > 0 {
+		lengthInBits += 16 * uint16(len(m.fifoValue))
+	}
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReadFifoQueueResponse) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReadFifoQueueResponse) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReadFifoQueueResponse) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadFileRecordRequest.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadFileRecordRequest.go
new file mode 100644
index 0000000..e4d1028
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadFileRecordRequest.go
@@ -0,0 +1,54 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReadFileRecordRequest struct {
+	items []ModbusPDUReadFileRecordRequestItem
+	ModbusPDU
+}
+
+func (m ModbusPDUReadFileRecordRequest) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Implicit Field (byteCount)
+	lengthInBits += 8
+
+	// Array field
+	if len(m.items) > 0 {
+		for _, element := range m.items {
+			lengthInBits += element.lengthInBits()
+		}
+	}
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReadFileRecordRequest) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReadFileRecordRequest) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReadFileRecordRequest) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadFileRecordRequestItem.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadFileRecordRequestItem.go
new file mode 100644
index 0000000..305fde5
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadFileRecordRequestItem.go
@@ -0,0 +1,58 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReadFileRecordRequestItem struct {
+	referenceType uint8
+	fileNumber    uint16
+	recordNumber  uint16
+	recordLength  uint16
+}
+
+func (m ModbusPDUReadFileRecordRequestItem) lengthInBits() uint16 {
+	var lengthInBits uint16 = 0
+
+	// Simple field (referenceType)
+	lengthInBits += 8
+
+	// Simple field (fileNumber)
+	lengthInBits += 16
+
+	// Simple field (recordNumber)
+	lengthInBits += 16
+
+	// Simple field (recordLength)
+	lengthInBits += 16
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReadFileRecordRequestItem) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReadFileRecordRequestItem) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReadFileRecordRequestItem) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadFileRecordResponse.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadFileRecordResponse.go
new file mode 100644
index 0000000..831f716
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadFileRecordResponse.go
@@ -0,0 +1,54 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReadFileRecordResponse struct {
+	items []ModbusPDUReadFileRecordResponseItem
+	ModbusPDU
+}
+
+func (m ModbusPDUReadFileRecordResponse) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Implicit Field (byteCount)
+	lengthInBits += 8
+
+	// Array field
+	if len(m.items) > 0 {
+		for _, element := range m.items {
+			lengthInBits += element.lengthInBits()
+		}
+	}
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReadFileRecordResponse) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReadFileRecordResponse) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReadFileRecordResponse) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadFileRecordResponseItem.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadFileRecordResponseItem.go
new file mode 100644
index 0000000..d6a1666
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadFileRecordResponseItem.go
@@ -0,0 +1,55 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReadFileRecordResponseItem struct {
+	referenceType uint8
+	data          []int8
+}
+
+func (m ModbusPDUReadFileRecordResponseItem) lengthInBits() uint16 {
+	var lengthInBits uint16 = 0
+
+	// Implicit Field (dataLength)
+	lengthInBits += 8
+
+	// Simple field (referenceType)
+	lengthInBits += 8
+
+	// Array field
+	if len(m.data) > 0 {
+		lengthInBits += 8 * uint16(len(m.data))
+	}
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReadFileRecordResponseItem) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReadFileRecordResponseItem) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReadFileRecordResponseItem) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadHoldingRegistersRequest.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadHoldingRegistersRequest.go
new file mode 100644
index 0000000..fd2f8cd
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadHoldingRegistersRequest.go
@@ -0,0 +1,51 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReadHoldingRegistersRequest struct {
+	startingAddress uint16
+	quantity        uint16
+	ModbusPDU
+}
+
+func (m ModbusPDUReadHoldingRegistersRequest) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Simple field (startingAddress)
+	lengthInBits += 16
+
+	// Simple field (quantity)
+	lengthInBits += 16
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReadHoldingRegistersRequest) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReadHoldingRegistersRequest) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReadHoldingRegistersRequest) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadHoldingRegistersResponse.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadHoldingRegistersResponse.go
new file mode 100644
index 0000000..dd28882
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadHoldingRegistersResponse.go
@@ -0,0 +1,52 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReadHoldingRegistersResponse struct {
+	value []int8
+	ModbusPDU
+}
+
+func (m ModbusPDUReadHoldingRegistersResponse) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Implicit Field (byteCount)
+	lengthInBits += 8
+
+	// Array field
+	if len(m.value) > 0 {
+		lengthInBits += 8 * uint16(len(m.value))
+	}
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReadHoldingRegistersResponse) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReadHoldingRegistersResponse) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReadHoldingRegistersResponse) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadInputRegistersRequest.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadInputRegistersRequest.go
new file mode 100644
index 0000000..ab2dfdc
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadInputRegistersRequest.go
@@ -0,0 +1,51 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReadInputRegistersRequest struct {
+	startingAddress uint16
+	quantity        uint16
+	ModbusPDU
+}
+
+func (m ModbusPDUReadInputRegistersRequest) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Simple field (startingAddress)
+	lengthInBits += 16
+
+	// Simple field (quantity)
+	lengthInBits += 16
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReadInputRegistersRequest) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReadInputRegistersRequest) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReadInputRegistersRequest) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadInputRegistersResponse.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadInputRegistersResponse.go
new file mode 100644
index 0000000..bd72898
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadInputRegistersResponse.go
@@ -0,0 +1,52 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReadInputRegistersResponse struct {
+	value []int8
+	ModbusPDU
+}
+
+func (m ModbusPDUReadInputRegistersResponse) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Implicit Field (byteCount)
+	lengthInBits += 8
+
+	// Array field
+	if len(m.value) > 0 {
+		lengthInBits += 8 * uint16(len(m.value))
+	}
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReadInputRegistersResponse) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReadInputRegistersResponse) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReadInputRegistersResponse) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersRequest.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersRequest.go
new file mode 100644
index 0000000..08bbca2
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersRequest.go
@@ -0,0 +1,68 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReadWriteMultipleHoldingRegistersRequest struct {
+	readStartingAddress  uint16
+	readQuantity         uint16
+	writeStartingAddress uint16
+	writeQuantity        uint16
+	value                []int8
+	ModbusPDU
+}
+
+func (m ModbusPDUReadWriteMultipleHoldingRegistersRequest) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Simple field (readStartingAddress)
+	lengthInBits += 16
+
+	// Simple field (readQuantity)
+	lengthInBits += 16
+
+	// Simple field (writeStartingAddress)
+	lengthInBits += 16
+
+	// Simple field (writeQuantity)
+	lengthInBits += 16
+
+	// Implicit Field (byteCount)
+	lengthInBits += 8
+
+	// Array field
+	if len(m.value) > 0 {
+		lengthInBits += 8 * uint16(len(m.value))
+	}
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReadWriteMultipleHoldingRegistersRequest) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReadWriteMultipleHoldingRegistersRequest) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReadWriteMultipleHoldingRegistersRequest) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersResponse.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersResponse.go
new file mode 100644
index 0000000..5a547d4
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersResponse.go
@@ -0,0 +1,52 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReadWriteMultipleHoldingRegistersResponse struct {
+	value []int8
+	ModbusPDU
+}
+
+func (m ModbusPDUReadWriteMultipleHoldingRegistersResponse) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Implicit Field (byteCount)
+	lengthInBits += 8
+
+	// Array field
+	if len(m.value) > 0 {
+		lengthInBits += 8 * uint16(len(m.value))
+	}
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReadWriteMultipleHoldingRegistersResponse) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReadWriteMultipleHoldingRegistersResponse) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReadWriteMultipleHoldingRegistersResponse) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReportServerIdRequest.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReportServerIdRequest.go
new file mode 100644
index 0000000..4e052cc
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReportServerIdRequest.go
@@ -0,0 +1,43 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReportServerIdRequest struct {
+	ModbusPDU
+}
+
+func (m ModbusPDUReportServerIdRequest) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReportServerIdRequest) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReportServerIdRequest) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReportServerIdRequest) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReportServerIdResponse.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReportServerIdResponse.go
new file mode 100644
index 0000000..dde37bd
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUReportServerIdResponse.go
@@ -0,0 +1,52 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUReportServerIdResponse struct {
+	value []int8
+	ModbusPDU
+}
+
+func (m ModbusPDUReportServerIdResponse) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Implicit Field (byteCount)
+	lengthInBits += 8
+
+	// Array field
+	if len(m.value) > 0 {
+		lengthInBits += 8 * uint16(len(m.value))
+	}
+
+	return lengthInBits
+}
+
+func (m ModbusPDUReportServerIdResponse) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUReportServerIdResponse) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUReportServerIdResponse) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteFileRecordRequest.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteFileRecordRequest.go
new file mode 100644
index 0000000..f74ac86
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteFileRecordRequest.go
@@ -0,0 +1,54 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUWriteFileRecordRequest struct {
+	items []ModbusPDUWriteFileRecordRequestItem
+	ModbusPDU
+}
+
+func (m ModbusPDUWriteFileRecordRequest) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Implicit Field (byteCount)
+	lengthInBits += 8
+
+	// Array field
+	if len(m.items) > 0 {
+		for _, element := range m.items {
+			lengthInBits += element.lengthInBits()
+		}
+	}
+
+	return lengthInBits
+}
+
+func (m ModbusPDUWriteFileRecordRequest) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUWriteFileRecordRequest) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUWriteFileRecordRequest) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteFileRecordRequestItem.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteFileRecordRequestItem.go
new file mode 100644
index 0000000..c664c52
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteFileRecordRequestItem.go
@@ -0,0 +1,63 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUWriteFileRecordRequestItem struct {
+	referenceType uint8
+	fileNumber    uint16
+	recordNumber  uint16
+	recordData    []int8
+}
+
+func (m ModbusPDUWriteFileRecordRequestItem) lengthInBits() uint16 {
+	var lengthInBits uint16 = 0
+
+	// Simple field (referenceType)
+	lengthInBits += 8
+
+	// Simple field (fileNumber)
+	lengthInBits += 16
+
+	// Simple field (recordNumber)
+	lengthInBits += 16
+
+	// Implicit Field (recordLength)
+	lengthInBits += 16
+
+	// Array field
+	if len(m.recordData) > 0 {
+		lengthInBits += 8 * uint16(len(m.recordData))
+	}
+
+	return lengthInBits
+}
+
+func (m ModbusPDUWriteFileRecordRequestItem) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUWriteFileRecordRequestItem) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUWriteFileRecordRequestItem) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteFileRecordResponse.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteFileRecordResponse.go
new file mode 100644
index 0000000..dd421a2
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteFileRecordResponse.go
@@ -0,0 +1,54 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUWriteFileRecordResponse struct {
+	items []ModbusPDUWriteFileRecordResponseItem
+	ModbusPDU
+}
+
+func (m ModbusPDUWriteFileRecordResponse) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Implicit Field (byteCount)
+	lengthInBits += 8
+
+	// Array field
+	if len(m.items) > 0 {
+		for _, element := range m.items {
+			lengthInBits += element.lengthInBits()
+		}
+	}
+
+	return lengthInBits
+}
+
+func (m ModbusPDUWriteFileRecordResponse) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUWriteFileRecordResponse) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUWriteFileRecordResponse) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteFileRecordResponseItem.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteFileRecordResponseItem.go
new file mode 100644
index 0000000..600c646
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteFileRecordResponseItem.go
@@ -0,0 +1,63 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUWriteFileRecordResponseItem struct {
+	referenceType uint8
+	fileNumber    uint16
+	recordNumber  uint16
+	recordData    []int8
+}
+
+func (m ModbusPDUWriteFileRecordResponseItem) lengthInBits() uint16 {
+	var lengthInBits uint16 = 0
+
+	// Simple field (referenceType)
+	lengthInBits += 8
+
+	// Simple field (fileNumber)
+	lengthInBits += 16
+
+	// Simple field (recordNumber)
+	lengthInBits += 16
+
+	// Implicit Field (recordLength)
+	lengthInBits += 16
+
+	// Array field
+	if len(m.recordData) > 0 {
+		lengthInBits += 8 * uint16(len(m.recordData))
+	}
+
+	return lengthInBits
+}
+
+func (m ModbusPDUWriteFileRecordResponseItem) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUWriteFileRecordResponseItem) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUWriteFileRecordResponseItem) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteMultipleCoilsRequest.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteMultipleCoilsRequest.go
new file mode 100644
index 0000000..aa37144
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteMultipleCoilsRequest.go
@@ -0,0 +1,60 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUWriteMultipleCoilsRequest struct {
+	startingAddress uint16
+	quantity        uint16
+	value           []int8
+	ModbusPDU
+}
+
+func (m ModbusPDUWriteMultipleCoilsRequest) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Simple field (startingAddress)
+	lengthInBits += 16
+
+	// Simple field (quantity)
+	lengthInBits += 16
+
+	// Implicit Field (byteCount)
+	lengthInBits += 8
+
+	// Array field
+	if len(m.value) > 0 {
+		lengthInBits += 8 * uint16(len(m.value))
+	}
+
+	return lengthInBits
+}
+
+func (m ModbusPDUWriteMultipleCoilsRequest) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUWriteMultipleCoilsRequest) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUWriteMultipleCoilsRequest) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteMultipleCoilsResponse.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteMultipleCoilsResponse.go
new file mode 100644
index 0000000..8870ac8
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteMultipleCoilsResponse.go
@@ -0,0 +1,51 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUWriteMultipleCoilsResponse struct {
+	startingAddress uint16
+	quantity        uint16
+	ModbusPDU
+}
+
+func (m ModbusPDUWriteMultipleCoilsResponse) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Simple field (startingAddress)
+	lengthInBits += 16
+
+	// Simple field (quantity)
+	lengthInBits += 16
+
+	return lengthInBits
+}
+
+func (m ModbusPDUWriteMultipleCoilsResponse) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUWriteMultipleCoilsResponse) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUWriteMultipleCoilsResponse) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersRequest.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersRequest.go
new file mode 100644
index 0000000..492c018
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersRequest.go
@@ -0,0 +1,60 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUWriteMultipleHoldingRegistersRequest struct {
+	startingAddress uint16
+	quantity        uint16
+	value           []int8
+	ModbusPDU
+}
+
+func (m ModbusPDUWriteMultipleHoldingRegistersRequest) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Simple field (startingAddress)
+	lengthInBits += 16
+
+	// Simple field (quantity)
+	lengthInBits += 16
+
+	// Implicit Field (byteCount)
+	lengthInBits += 8
+
+	// Array field
+	if len(m.value) > 0 {
+		lengthInBits += 8 * uint16(len(m.value))
+	}
+
+	return lengthInBits
+}
+
+func (m ModbusPDUWriteMultipleHoldingRegistersRequest) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUWriteMultipleHoldingRegistersRequest) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUWriteMultipleHoldingRegistersRequest) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersResponse.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersResponse.go
new file mode 100644
index 0000000..28592f7
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersResponse.go
@@ -0,0 +1,51 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUWriteMultipleHoldingRegistersResponse struct {
+	startingAddress uint16
+	quantity        uint16
+	ModbusPDU
+}
+
+func (m ModbusPDUWriteMultipleHoldingRegistersResponse) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Simple field (startingAddress)
+	lengthInBits += 16
+
+	// Simple field (quantity)
+	lengthInBits += 16
+
+	return lengthInBits
+}
+
+func (m ModbusPDUWriteMultipleHoldingRegistersResponse) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUWriteMultipleHoldingRegistersResponse) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUWriteMultipleHoldingRegistersResponse) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteSingleCoilRequest.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteSingleCoilRequest.go
new file mode 100644
index 0000000..e7cf3e5
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteSingleCoilRequest.go
@@ -0,0 +1,51 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUWriteSingleCoilRequest struct {
+	address uint16
+	value   uint16
+	ModbusPDU
+}
+
+func (m ModbusPDUWriteSingleCoilRequest) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Simple field (address)
+	lengthInBits += 16
+
+	// Simple field (value)
+	lengthInBits += 16
+
+	return lengthInBits
+}
+
+func (m ModbusPDUWriteSingleCoilRequest) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUWriteSingleCoilRequest) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUWriteSingleCoilRequest) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteSingleCoilResponse.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteSingleCoilResponse.go
new file mode 100644
index 0000000..e3e7af9
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteSingleCoilResponse.go
@@ -0,0 +1,51 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUWriteSingleCoilResponse struct {
+	address uint16
+	value   uint16
+	ModbusPDU
+}
+
+func (m ModbusPDUWriteSingleCoilResponse) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Simple field (address)
+	lengthInBits += 16
+
+	// Simple field (value)
+	lengthInBits += 16
+
+	return lengthInBits
+}
+
+func (m ModbusPDUWriteSingleCoilResponse) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUWriteSingleCoilResponse) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUWriteSingleCoilResponse) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteSingleRegisterRequest.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteSingleRegisterRequest.go
new file mode 100644
index 0000000..9230fa3
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteSingleRegisterRequest.go
@@ -0,0 +1,51 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUWriteSingleRegisterRequest struct {
+	address uint16
+	value   uint16
+	ModbusPDU
+}
+
+func (m ModbusPDUWriteSingleRegisterRequest) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Simple field (address)
+	lengthInBits += 16
+
+	// Simple field (value)
+	lengthInBits += 16
+
+	return lengthInBits
+}
+
+func (m ModbusPDUWriteSingleRegisterRequest) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUWriteSingleRegisterRequest) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUWriteSingleRegisterRequest) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteSingleRegisterResponse.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteSingleRegisterResponse.go
new file mode 100644
index 0000000..096d388
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusPDUWriteSingleRegisterResponse.go
@@ -0,0 +1,51 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusPDUWriteSingleRegisterResponse struct {
+	address uint16
+	value   uint16
+	ModbusPDU
+}
+
+func (m ModbusPDUWriteSingleRegisterResponse) lengthInBits() uint16 {
+	var lengthInBits uint16 = m.ModbusPDU.lengthInBits()
+
+	// Simple field (address)
+	lengthInBits += 16
+
+	// Simple field (value)
+	lengthInBits += 16
+
+	return lengthInBits
+}
+
+func (m ModbusPDUWriteSingleRegisterResponse) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusPDUWriteSingleRegisterResponse) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusPDUWriteSingleRegisterResponse) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusSerialADU.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusSerialADU.go
new file mode 100644
index 0000000..098a859
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusSerialADU.go
@@ -0,0 +1,61 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusSerialADU struct {
+	transactionId uint16
+	length        uint16
+	address       uint8
+	pdu           ModbusPDU
+}
+
+func (m ModbusSerialADU) lengthInBits() uint16 {
+	var lengthInBits uint16 = 0
+
+	// Simple field (transactionId)
+	lengthInBits += 16
+
+	// Reserved Field (reserved)
+	lengthInBits += 16
+
+	// Simple field (length)
+	lengthInBits += 16
+
+	// Simple field (address)
+	lengthInBits += 8
+
+	// Simple field (pdu)
+	lengthInBits += m.pdu.lengthInBits()
+
+	return lengthInBits
+}
+
+func (m ModbusSerialADU) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusSerialADU) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusSerialADU) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusTcpADU.go b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusTcpADU.go
new file mode 100644
index 0000000..04788d4
--- /dev/null
+++ b/sandbox/plc4go/generated-sources/plc4go/go/modbus/readwrite/ModbusTcpADU.go
@@ -0,0 +1,60 @@
+//
+// 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 readwrite
+
+import "plc4x.apache.org/plc4go-modbus-driver/0.8.0/src/plc4go/spi"
+
+type ModbusTcpADU struct {
+	transactionIdentifier uint16
+	unitIdentifier        uint8
+	pdu                   ModbusPDU
+}
+
+func (m ModbusTcpADU) lengthInBits() uint16 {
+	var lengthInBits uint16 = 0
+
+	// Simple field (transactionIdentifier)
+	lengthInBits += 16
+
+	// Const Field (protocolIdentifier)
+	lengthInBits += 16
+
+	// Implicit Field (length)
+	lengthInBits += 16
+
+	// Simple field (unitIdentifier)
+	lengthInBits += 8
+
+	// Simple field (pdu)
+	lengthInBits += m.pdu.lengthInBits()
+
+	return lengthInBits
+}
+
+func (m ModbusTcpADU) lengthInBytes() uint16 {
+	return m.lengthInBits() / 8
+}
+
+func (m ModbusTcpADU) parse(io spi.ReadBuffer) {
+	// TODO: Implement ...
+}
+
+func (m ModbusTcpADU) serialize(io spi.WriteBuffer) {
+	// TODO: Implement ...
+}
diff --git a/sandbox/plc4go/go.mod b/sandbox/plc4go/go.mod
new file mode 100644
index 0000000..44b7ec5
--- /dev/null
+++ b/sandbox/plc4go/go.mod
@@ -0,0 +1,18 @@
+// 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.
+//
+module plc4x.apache.org/plc4go-modbus-driver/0.8.0
+
+go 1.14
diff --git a/sandbox/plc4go/pom.xml b/sandbox/plc4go/pom.xml
index 90c81e9..c519a1d 100644
--- a/sandbox/plc4go/pom.xml
+++ b/sandbox/plc4go/pom.xml
@@ -17,7 +17,8 @@
   specific language governing permissions and limitations
   under the License.
   -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
   <modelVersion>4.0.0</modelVersion>
 
@@ -28,30 +29,77 @@
   </parent>
 
   <artifactId>plc4go</artifactId>
-  <packaging>pom</packaging>
+  <packaging>mvn-golang</packaging>
 
   <name>Sandbox: PLC4Go</name>
   <description>Implementation of the protocol adapters for usage as Go(lang) library.</description>
 
-  <plugins>
-    <plugin>
-      <groupId>com.igormaznitsa</groupId>
-      <artifactId>mvn-golang-wrapper</artifactId>
-      <version>2.3.5</version>
-      <extensions>true</extensions>
-      <executions>
-        <execution>
-          <goals>
-            <goal>run</goal>
-          </goals>
-          <configuration>
-            <packages>
-              <package>main.go</package>
-            </packages>
-          </configuration>
-        </execution>
-      </executions>
-    </plugin>
-  </plugins>
+  <build>
+    <sourceDirectory>src</sourceDirectory>
+    <plugins>
+      <!--
+        Generate the driver code.
+      -->
+      <plugin>
+        <groupId>org.apache.plc4x.plugins</groupId>
+        <artifactId>plc4x-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>generate-driver-modbus</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>generate-driver</goal>
+            </goals>
+            <configuration>
+              <protocolName>modbus</protocolName>
+              <languageName>go</languageName>
+              <outputFlavor>read-write</outputFlavor>
+              <outputDir>${project.basedir}/generated-sources</outputDir>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <groupId>com.igormaznitsa</groupId>
+        <artifactId>mvn-golang-wrapper</artifactId>
+        <version>2.3.5</version>
+        <extensions>true</extensions>
+        <executions>
+          <execution>
+            <goals>
+              <goal>run</goal>
+            </goals>
+            <configuration>
+              <packages>
+                <package>main.go</package>
+              </packages>
+              <sources>src,generated-sources</sources>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <!-- This dependency is just to ensure thrift is built first -->
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-build-utils-language-go</artifactId>
+      <version>0.8.0-SNAPSHOT</version>
+      <!-- Scope is 'provided' as this way it's not shipped with the driver -->
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-protocols-modbus</artifactId>
+      <version>0.8.0-SNAPSHOT</version>
+      <!-- Scope is 'provided' as this way it's not shipped with the driver -->
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+
 
 </project>
\ No newline at end of file
diff --git a/sandbox/plc4go/src/modbus.go b/sandbox/plc4go/src/modbus.go
new file mode 100644
index 0000000..c471e74
--- /dev/null
+++ b/sandbox/plc4go/src/modbus.go
@@ -0,0 +1,16 @@
+// 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 modbus
diff --git a/sandbox/plc4go/src/plc4go/modbus/readwrite/Message.go b/sandbox/plc4go/src/plc4go/modbus/readwrite/Message.go
deleted file mode 100644
index 3c47b6f..0000000
--- a/sandbox/plc4go/src/plc4go/modbus/readwrite/Message.go
+++ /dev/null
@@ -1,10 +0,0 @@
-package readwrite
-
-import (
-
-)
-
-type Message interface {
-    lengthInBytes() int16
-    lengthInBits() int16
-}
\ No newline at end of file
diff --git a/sandbox/plc4go/src/plc4go/spi/Message.go b/sandbox/plc4go/src/plc4go/spi/Message.go
new file mode 100644
index 0000000..83a1075
--- /dev/null
+++ b/sandbox/plc4go/src/plc4go/spi/Message.go
@@ -0,0 +1,24 @@
+//
+// 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 spi
+
+type Message interface {
+	lengthInBytes() uint16
+	lengthInBits() uint16
+}
diff --git a/sandbox/plc4go/src/plc4go/spi/ReadBuffer.go b/sandbox/plc4go/src/plc4go/spi/ReadBuffer.go
new file mode 100644
index 0000000..5f1996e
--- /dev/null
+++ b/sandbox/plc4go/src/plc4go/spi/ReadBuffer.go
@@ -0,0 +1,22 @@
+//
+// 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 spi
+
+type ReadBuffer struct {
+}
diff --git a/sandbox/plc4go/src/plc4go/spi/WriteBuffer.go b/sandbox/plc4go/src/plc4go/spi/WriteBuffer.go
new file mode 100644
index 0000000..2684e51
--- /dev/null
+++ b/sandbox/plc4go/src/plc4go/spi/WriteBuffer.go
@@ -0,0 +1,22 @@
+//
+// 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 spi
+
+type WriteBuffer struct {
+}
diff --git a/sandbox/pom.xml b/sandbox/pom.xml
index 1b438bf..e22fe3a 100644
--- a/sandbox/pom.xml
+++ b/sandbox/pom.xml
@@ -94,6 +94,15 @@
       </modules>
     </profile>
 
+
+    <!-- Build PLC4X including the Go modules -->
+    <profile>
+      <id>with-go</id>
+      <modules>
+        <module>plc4go</module>
+      </modules>
+    </profile>
+
     <!-- Build PLC4X including the .Net modules -->
     <profile>
       <id>with-dotnet</id>