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

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


The following commit(s) were added to refs/heads/feature/plc4rs by this push:
     new 57e5d0339f Rust Codegeneration generates Cargo file and lib.rs
57e5d0339f is described below

commit 57e5d0339f2d715a88b560b2726b464a57e8468e
Author: julian <[email protected]>
AuthorDate: Sun Jun 5 22:30:48 2022 +0200

    Rust Codegeneration generates Cargo file and lib.rs
---
 .../plc4x/language/rust/RustLanguageOutput.java    |  49 ++
 .../language/rust/RustLanguageTemplateHelper.java  |  84 +-
 .../src/main/resources/templates/rust/Cargo.toml   |  26 +
 .../templates/rust/complex-type-template.rs.ftlh   |  49 +-
 .../templates/rust/data-io-template.rs.ftlh        | 907 +++++++++++----------
 .../resources/templates/rust/enum-template.rs.ftlh |  13 +-
 plc4rust/src/read_buffer.rs                        |  12 +-
 7 files changed, 660 insertions(+), 480 deletions(-)

diff --git 
a/code-generation/language-rust/src/main/java/org/apache/plc4x/language/rust/RustLanguageOutput.java
 
b/code-generation/language-rust/src/main/java/org/apache/plc4x/language/rust/RustLanguageOutput.java
index f155610ea7..8edf948337 100644
--- 
a/code-generation/language-rust/src/main/java/org/apache/plc4x/language/rust/RustLanguageOutput.java
+++ 
b/code-generation/language-rust/src/main/java/org/apache/plc4x/language/rust/RustLanguageOutput.java
@@ -20,14 +20,22 @@ package org.apache.plc4x.language.rust;
 
 import freemarker.template.Configuration;
 import freemarker.template.Template;
+import org.apache.commons.io.FileUtils;
 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 
org.apache.plc4x.plugins.codegenerator.types.exceptions.GenerationException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.nio.file.StandardCopyOption;
 import java.util.*;
 
 public class RustLanguageOutput extends FreemarkerLanguageOutput {
@@ -94,4 +102,45 @@ public class RustLanguageOutput extends 
FreemarkerLanguageOutput {
         }
  */
     }
+
+    @Override
+    public void generate(File outputDir, String languageName, String 
protocolName, String outputFlavor, Map<String, TypeDefinition> types, 
Map<String, String> options) throws GenerationException {
+        super.generate(outputDir, languageName, protocolName, outputFlavor, 
types, options);
+        // Add post generation logic here
+        try {
+            InputStream inputStream = 
this.getClass().getClassLoader().getResourceAsStream("templates/rust/Cargo.toml");
+            if (inputStream == null) {
+                throw new RuntimeException("Unable to generate Cargo.toml");
+            }
+            java.nio.file.Files.copy(
+                inputStream,
+                outputDir.toPath().resolve("Cargo.toml"),
+                StandardCopyOption.REPLACE_EXISTING);
+            inputStream.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        // Generate lib.rs
+        try {
+            StringBuilder sb = new StringBuilder();
+
+            Collection<File> files = 
FileUtils.listFiles(outputDir.toPath().resolve("src").toFile(), new 
String[]{"rs"}, false);
+
+            for (File file : files) {
+                sb.append("mod " + file.getName().split("\\.")[0] + ";\n");
+            }
+            sb.append("\n");
+            sb.append("#[cfg(test)]\n" +
+                "mod test {\n" +
+                "\n" +
+                "    #[test]\n" +
+                "    fn test() {\n" +
+                "        println!(\"Hello world!\");\n" +
+                "    }\n" +
+                "}");
+            
FileUtils.writeStringToFile(outputDir.toPath().resolve("src").resolve("lib.rs").toFile(),
 sb.toString(), Charset.defaultCharset());
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
 }
diff --git 
a/code-generation/language-rust/src/main/java/org/apache/plc4x/language/rust/RustLanguageTemplateHelper.java
 
b/code-generation/language-rust/src/main/java/org/apache/plc4x/language/rust/RustLanguageTemplateHelper.java
index bafa9e6f55..0fbb1bdc54 100644
--- 
a/code-generation/language-rust/src/main/java/org/apache/plc4x/language/rust/RustLanguageTemplateHelper.java
+++ 
b/code-generation/language-rust/src/main/java/org/apache/plc4x/language/rust/RustLanguageTemplateHelper.java
@@ -25,6 +25,7 @@ import 
org.apache.plc4x.plugins.codegenerator.language.mspec.model.definitions.D
 import 
org.apache.plc4x.plugins.codegenerator.language.mspec.model.definitions.DefaultEnumTypeDefinition;
 import 
org.apache.plc4x.plugins.codegenerator.language.mspec.model.fields.DefaultDiscriminatorField;
 import 
org.apache.plc4x.plugins.codegenerator.language.mspec.model.fields.DefaultSwitchField;
+import 
org.apache.plc4x.plugins.codegenerator.language.mspec.model.references.DefaultArrayTypeReference;
 import 
org.apache.plc4x.plugins.codegenerator.language.mspec.model.references.DefaultEnumTypeReference;
 import 
org.apache.plc4x.plugins.codegenerator.language.mspec.model.terms.DefaultBooleanLiteral;
 import 
org.apache.plc4x.plugins.codegenerator.language.mspec.model.terms.DefaultStringLiteral;
@@ -156,14 +157,27 @@ public class RustLanguageTemplateHelper extends 
BaseFreemarkerLanguageTemplateHe
         return "";
     }
 
-    public List<String> generateImports(TypeDefinition typeDefinition) {
+    private static List<String[]> getParserArgsImports(TypeDefinition 
typeDefinition) {
+        List<String[]> imports = new ArrayList<>();
+        if (typeDefinition.getParserArguments().isPresent()) {
+            for (Argument argument : 
typeDefinition.getParserArguments().get()) {
+                TypeReference type = argument.getType();
+                if (type instanceof DefaultEnumTypeReference) {
+                    imports.add(new String[]{((DefaultEnumTypeReference) 
type).getName(), ((DefaultEnumTypeReference) type).getName()});
+                }
+            }
+        }
+        return imports;
+    }
+
+    public List<String[]> generateImports(TypeDefinition typeDefinition) {
         // Iterate all Types to see what kind of other Enums / Objects are 
references
-        List<String> imports = new ArrayList<>();
+        List<String[]> imports = new ArrayList<>();
         if (typeDefinition instanceof EnumTypeDefinition) {
             for (String constantName : ((EnumTypeDefinition) 
typeDefinition).getConstantNames()) {
                 TypeReference constantType = ((EnumTypeDefinition) 
typeDefinition).getConstantType(constantName);
                 if (constantType instanceof DefaultEnumTypeReference) {
-                    imports.add(((DefaultEnumTypeReference) 
constantType).getName());
+                    imports.add(new String[]{((DefaultEnumTypeReference) 
constantType).getName(), ((DefaultEnumTypeReference) constantType).getName()});
                 }
             }
         }
@@ -171,11 +185,43 @@ public class RustLanguageTemplateHelper extends 
BaseFreemarkerLanguageTemplateHe
             for (Field field : ((DefaultComplexTypeDefinition) 
typeDefinition).getFields()) {
                 if (field instanceof DefaultSwitchField) {
                     for (DiscriminatedComplexTypeDefinition subclass : 
((DefaultSwitchField) field).getCases()) {
-                        imports.add(subclass.getName());
+                        imports.add(new String[]{subclass.getName(), 
subclass.getName()});
+                        // Also add options type
+                        imports.add(new String[]{subclass.getName(), 
subclass.getName() + "Options"});
                     }
                 }
             }
         }
+        imports.addAll(getParserArgsImports(typeDefinition));
+        // If it has a parent type, also generate imports for the paraent type
+        if (typeDefinition instanceof ComplexTypeDefinition) {
+            if (((ComplexTypeDefinition) 
typeDefinition).getParentType().isPresent()) {
+                imports.addAll(getParserArgsImports(((ComplexTypeDefinition) 
typeDefinition).getParentType().get()));
+            }
+
+            // Add Imports for fields
+            for (Field field : ((ComplexTypeDefinition) 
typeDefinition).getFields()) {
+                if (field instanceof TypedField) {
+                    TypeReference type = ((TypedField) field).getType();
+                    if (type instanceof ComplexTypeReference) {
+                        String typeName = ((ComplexTypeReference) 
type).getName();
+                        imports.add(new String[]{typeName, typeName});
+                    } else if (type instanceof DefaultArrayTypeReference) {
+                        // TODO refactor to make this more elgant
+                        TypeReference elementTypeReference = 
((DefaultArrayTypeReference) type).getElementTypeReference();
+                        if (elementTypeReference instanceof 
ComplexTypeReference) {
+                            String typeName = ((ComplexTypeReference) 
elementTypeReference).getName();
+                            imports.add(new String[]{typeName, typeName});
+                        }
+                    } else if (type instanceof DefaultEnumTypeReference) {
+                        String typeName = ((DefaultEnumTypeReference) 
type).getName();
+                        imports.add(new String[]{typeName, typeName});
+                    }
+                }
+            }
+        }
+
+
         return imports;
     }
 
@@ -314,15 +360,35 @@ public class RustLanguageTemplateHelper extends 
BaseFreemarkerLanguageTemplateHe
         });
     }
 
+    public String getReadFunctionCall(TypeReference typeReference) {
+        if (!(typeReference instanceof SimpleTypeReference)) {
+            throw new RuntimeException("Not implemented yet: " + 
typeReference);
+        }
+        SimpleTypeReference simpleTypeReference = (SimpleTypeReference) 
typeReference;
+        switch (simpleTypeReference.getBaseType()) {
+            case BIT:
+                return "read_bit()?";
+            case UINT:
+                IntegerTypeReference unsignedIntegerTypeReference = 
(IntegerTypeReference) simpleTypeReference;
+                if (unsignedIntegerTypeReference.getSizeInBits() < 8) {
+                    return "read_u_n(" + 
unsignedIntegerTypeReference.getSizeInBits() + ")? as u8";
+                }
+                if (unsignedIntegerTypeReference.getSizeInBits() == 8) {
+                    return "read_u8()?";
+                }
+        }
+        throw new RuntimeException("Not implemented yet: " + typeReference);
+    }
+
     public String getLanguageTypeNameForTypeReference(TypeReference 
typeReference, boolean allowPrimitive) {
         Objects.requireNonNull(typeReference);
         if (typeReference instanceof ArrayTypeReference) {
             final ArrayTypeReference arrayTypeReference = (ArrayTypeReference) 
typeReference;
-            if (arrayTypeReference.getElementTypeReference().isByteBased()) {
-                return 
getLanguageTypeNameForTypeReference(arrayTypeReference.getElementTypeReference(),
 allowPrimitive) + "[]";
-            } else {
-                return "List<" + 
getLanguageTypeNameForTypeReference(arrayTypeReference.getElementTypeReference(),
 false) + ">";
-            }
+//            if (arrayTypeReference.getElementTypeReference().isByteBased()) {
+                return "Vec<" + 
getLanguageTypeNameForTypeReference(arrayTypeReference.getElementTypeReference(),
 allowPrimitive) + ">";
+//            } else {
+//                return "List<" + 
getLanguageTypeNameForTypeReference(arrayTypeReference.getElementTypeReference(),
 false) + ">";
+//            }
         }
         // DataIo data-types always have properties of type PlcValue
         if (typeReference.isDataIoTypeReference()) {
diff --git 
a/code-generation/language-rust/src/main/resources/templates/rust/Cargo.toml 
b/code-generation/language-rust/src/main/resources/templates/rust/Cargo.toml
new file mode 100644
index 0000000000..2014320c15
--- /dev/null
+++ b/code-generation/language-rust/src/main/resources/templates/rust/Cargo.toml
@@ -0,0 +1,26 @@
+# 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]
+name = "plc4x"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at 
https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+plc4rust = {path = "../../../../"}
\ No newline at end of file
diff --git 
a/code-generation/language-rust/src/main/resources/templates/rust/complex-type-template.rs.ftlh
 
b/code-generation/language-rust/src/main/resources/templates/rust/complex-type-template.rs.ftlh
index 57913bb7de..bda8b5dfc6 100644
--- 
a/code-generation/language-rust/src/main/resources/templates/rust/complex-type-template.rs.ftlh
+++ 
b/code-generation/language-rust/src/main/resources/templates/rust/complex-type-template.rs.ftlh
@@ -26,7 +26,8 @@
 <#-- @ftlvariable name="tracer" 
type="org.apache.plc4x.plugins.codegenerator.protocol.freemarker.Tracer" -->
 <#-- @ftlvariable name="type" 
type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition"
 -->
 <#-- Declare the name and type of variables declared locally inside the 
template -->
-${helper.packageName(protocolName, languageName, outputFlavor)?replace(".", 
"/")}/${type.name}.rs
+src/${type.name}.rs
+<#--${helper.packageName(protocolName, languageName, 
outputFlavor)?replace(".", "/")}/${type.name}.rs-->
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -48,24 +49,30 @@ ${helper.packageName(protocolName, languageName, 
outputFlavor)?replace(".", "/")
 // package ${helper.packageName(protocolName, languageName, outputFlavor)};
 
 // Code generated by code-generation. DO NOT EDIT.
+use std::io::{Error, ErrorKind, Read, Write};
+use plc4rust::{Message, NoOption};
+use plc4rust::read_buffer::ReadBuffer;
+use plc4rust::write_buffer::WriteBuffer;
+
 <#list helper.generateImports(type) as import>
-<#if type.name != import>
+<#if type.name != import[import?size - 1]>
 <#--  File -> Struct  -->
-use crate::${import}::${import};
+use crate::<#list import as path>${path}<#sep>::</#sep></#list>;
 </#if>
 </#list>
 
 <#--<#if helper.needsParserArguments(type)>-->
+#[derive(PartialEq, Debug, Clone)]
 pub struct ${type.name}Options {
 <#if type.parserArguments?? && !type.parserArguments.isEmpty()>
 <#list type.parserArguments.orElseThrow() as arg>
-    ${arg.name}: 
${helper.getLanguageTypeNameForTypeReference(arg.type)}<#sep>, </#sep>
+    pub ${arg.name}: 
${helper.getLanguageTypeNameForTypeReference(arg.type)}<#sep>, </#sep>
 </#list>
 </#if>
 <#if !type.parentType.isEmpty()>
 <#if type.parentType.get().parserArguments?? && 
!type.parentType.get().parserArguments.isEmpty()>
 <#list type.parentType.get().parserArguments.orElseThrow() as arg>
-    ${arg.name}: 
${helper.getLanguageTypeNameForTypeReference(arg.type)}<#sep>, </#sep>
+    pub ${arg.name}: 
${helper.getLanguageTypeNameForTypeReference(arg.type)}<#sep>, </#sep>
 </#list>
 </#if>
 </#if>
@@ -75,7 +82,7 @@ pub struct ${type.name}Options {
 #[derive(PartialEq, Debug, Clone)]
 pub enum ${type.name} {
 <#list helper.getSubtypes(type) as subtype>
-    ${subtype.name}(${subtype.name}::${subtype.name})<#sep>,</#sep>
+    ${subtype.name}(${subtype.name})<#sep>,</#sep>
 </#list>
 }
 
@@ -99,8 +106,9 @@ impl Message for ${type.name} {
 
     fn parse<T: Read>(reader: &mut ReadBuffer<T>, parameter: Option<Self::P>) 
-> Result<Self::M, Error> {
         // (Re-)define the options
+        let parameter = parameter.unwrap();
     <#list type.parserArguments.orElseThrow() as arg>
-        let ${arg.name} = parameter.unwrap().${arg.name};
+        let ${arg.name} = parameter.${arg.name};
     </#list>
     <#list type.fields as field>
         <#if helper.isSwitchField(field)>
@@ -108,7 +116,6 @@ impl Message for ${type.name} {
         <#list field.cases as aCase>
             <#assign n=aCase.discriminatorValueTerms?size - 1>
             <#assign m=field.getDiscriminatorExpressions()?size - 1>
-<#--            ${helper.sink(n)}-->
             (<#list 0..m as i><#if i <= n><#assign 
caseType=field.getDiscriminatorExpressions()[i]><#assign 
term=aCase.discriminatorValueTerms[i]>${helper.formatLiteral(caseType.typeReference,
 term)}<#else>_</#if><#sep>, </#sep></#list>) => {
                 
Ok(${type.name}::${aCase.name}(${aCase.name}::parse::<T>(reader, 
Some(${aCase.name}Options {
                 <#if type.parserArguments?? && !type.parserArguments.isEmpty()>
@@ -120,16 +127,40 @@ impl Message for ${type.name} {
 <#--                ${helper.sink(aCase)}-->
             }
         </#list>
+            _ => {
+                panic!("Unable to parse!");
+            }
         }
         <#else>
-        read ${field}
+        let ${field.name} = reader.${helper.getReadFunctionCall(field.type)};
         </#if>
 <#--        ${helper.generateFieldParseCode(field)}-->
     </#list>
     }
 }
 <#else>
+#[derive(PartialEq, Debug, Clone)]
 pub struct ${type.name} {
+    <#list type.fields as field>
+    pub ${field.name}: 
${helper.getLanguageTypeNameForTypeReference(field.type)}<#sep>,</#sep>
+    </#list>
+}
+
+impl Message for ${type.name} {
+    type M = ${type.name};
+    type P = ${type.name}Options;
+
+    fn get_length_in_bits(&self) -> u32 {
+        todo!()
+    }
+
+    fn serialize<T: Write>(&self, writer: &mut WriteBuffer<T>) -> 
Result<usize, Error> {
+        todo!()
+    }
+
+    fn parse<T: Read>(reader: &mut ReadBuffer<T>, parameter: Option<Self::P>) 
-> Result<Self::M, Error> {
+        todo!()
+    }
 }
 </#if>
 
diff --git 
a/code-generation/language-rust/src/main/resources/templates/rust/data-io-template.rs.ftlh
 
b/code-generation/language-rust/src/main/resources/templates/rust/data-io-template.rs.ftlh
index 3c9c9032e7..98e45e60e6 100644
--- 
a/code-generation/language-rust/src/main/resources/templates/rust/data-io-template.rs.ftlh
+++ 
b/code-generation/language-rust/src/main/resources/templates/rust/data-io-template.rs.ftlh
@@ -25,7 +25,8 @@
 <#-- @ftlvariable name="helper" 
type="org.apache.plc4x.language.rust.RustLanguageTemplateHelper" -->
 <#-- @ftlvariable name="tracer" 
type="org.apache.plc4x.plugins.codegenerator.protocol.freemarker.Tracer" -->
 <#-- @ftlvariable name="type" 
type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition"
 -->
-${helper.packageName(protocolName, languageName, outputFlavor)?replace(".", 
"/")}/${type.name}.rs
+src/${type.name}.rs
+<#--${helper.packageName(protocolName, languageName, 
outputFlavor)?replace(".", "/")}/${type.name}.rs-->
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -44,477 +45,477 @@ ${helper.packageName(protocolName, languageName, 
outputFlavor)?replace(".", "/")
  * specific language governing permissions and limitations
  * under the License.
  */
-package ${helper.packageName(protocolName, languageName, outputFlavor)};
+<#--package ${helper.packageName(protocolName, languageName, outputFlavor)};-->
 
-import static org.apache.plc4x.java.spi.generation.StaticHelper.*;
+<#--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.SerializationException;
-import org.apache.plc4x.java.spi.generation.ReadBuffer;
-import org.apache.plc4x.java.spi.generation.WriteBuffer;
-import org.apache.plc4x.java.spi.generation.ByteOrder;
-import ${helper.packageName(protocolName, languageName, outputFlavor)}.*;
-import org.apache.plc4x.java.spi.values.*;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+<#--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.SerializationException;-->
+<#--import org.apache.plc4x.java.spi.generation.ReadBuffer;-->
+<#--import org.apache.plc4x.java.spi.generation.WriteBuffer;-->
+<#--import org.apache.plc4x.java.spi.generation.ByteOrder;-->
+<#--import ${helper.packageName(protocolName, languageName, 
outputFlavor)}.*;-->
+<#--import org.apache.plc4x.java.spi.values.*;-->
+<#--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;
+<#--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;-->
 
-// Code generated by code-generation. DO NOT EDIT.
+<#--// Code generated by code-generation. DO NOT EDIT.-->
 
-<#-- TODO: the code below implies that parserArguments will be null if not 
present... not pretty  -->
-<#if type.parserArguments.isPresent()><#assign 
parserArguments=type.parserArguments.orElseThrow()></#if>
-public class ${type.name} {
+<#--&lt;#&ndash; TODO: the code below implies that parserArguments will be 
null if not present... not pretty  &ndash;&gt;-->
+<#--<#if type.parserArguments.isPresent()><#assign 
parserArguments=type.parserArguments.orElseThrow()></#if>-->
+<#--public class ${type.name} {-->
 
-    private static final Logger LOGGER = 
LoggerFactory.getLogger(${type.name}.class);
-    public static PlcValue staticParse(ReadBuffer readBuffer<#if 
type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as 
parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type,
 false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) throws 
ParseException {
-        <#assign defaultCaseOutput=false>
-        <#assign 
dataIoTypeDefinition=type.asDataIoTypeDefinition().orElseThrow()>
-        <#list dataIoTypeDefinition.switchField.orElseThrow().cases as case>
-            <@compress single_line=true>
-                <#if case.discriminatorValueTerms?has_content>
-                    if(
-                    <#list case.discriminatorValueTerms as 
discriminatorValueTerm>
-                        <#assign 
discriminatorExpression=dataIoTypeDefinition.switchField.orElseThrow().discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow()>
-                        <#assign 
discriminatorType=helper.getDiscriminatorTypes()[discriminatorExpression.name]>
-                        EvaluationHelper.equals(
-                        
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(), 
discriminatorType, discriminatorExpression, parserArguments)},
-                        <#if discriminatorType.isEnumTypeReference()>
-                        
${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
 discriminatorType, discriminatorValueTerm, parserArguments)}
-                        <#else>
-                        
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(), 
discriminatorType, discriminatorValueTerm, parserArguments)}
-                        </#if>
-                    )
-                        <#sep> && </#sep>
-                    </#list>
-                    )
-                <#else>
-                    <#assign defaultCaseOutput=true>
-                </#if>
-            </@compress> { // ${case.name}
-            <#assign valueDefined=false>
-            <#list case.fields as field>
-                <#switch field.typeName>
-                    <#case "array">
-                        <#assign arrayField = 
field.asArrayField().orElseThrow()>
-                        <#assign 
elementTypeReference=arrayField.type.elementTypeReference>
-            // Array field (${arrayField.name})
-            <#-- Only update curPos if the length expression uses it -->
-                        <#if arrayField.loopExpression.contains("curPos")>
-            curPos = readBuffer.getPos() - startPos;
-                        </#if>
-            <#-- If this is a count array, we can directly initialize an array 
with the given size -->
-                        <#if field.isCountArrayField()>
-            // Count array
-            if(${helper.toParseExpression(arrayField, helper.intTypeReference, 
arrayField.loopExpression,parserArguments)} > Integer.MAX_VALUE) {
-                throw new ParseException("Array count of " + 
(${helper.toParseExpression(arrayField, helper.intTypeReference, 
arrayField.loopExpression,parserArguments)}) + " exceeds the maximum allowed 
count of " + Integer.MAX_VALUE);
-            }
-            List<PlcValue> ${arrayField.name};
-            {
-                int itemCount = (int) ${helper.toParseExpression(arrayField, 
helper.intTypeReference, arrayField.loopExpression,parserArguments)};
-                ${arrayField.name} = new LinkedList<>();
-                for(int curItem = 0; curItem < itemCount; curItem++) {
-                    ${arrayField.name}.add(new 
${helper.getPlcValueTypeForTypeReference(elementTypeReference)}((${helper.getLanguageTypeNameForTypeReference(elementTypeReference,
 false)}) <#if 
elementTypeReference.isSimpleTypeReference()>${helper.getReadBufferReadMethodCall(elementTypeReference.asSimpleTypeReference().orElseThrow(),
 "", 
arrayField)})<#else>${elementTypeReference.asComplexTypeReference().orElseThrow().name}IO.staticParse(readBuffer<#if
 elementTypeReference.params.isPresen [...]
-                }
-            }
-            <#-- 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 arrayField.isLengthArrayField()>
-            // Length array
-            long _${arrayField.name}Length = 
${helper.toParseExpression(arrayField, helper.intTypeReference, 
arrayField.loopExpression,parserArguments)};
-            long ${arrayField.name}EndPos = readBuffer.getPos() + 
_${arrayField.name}Length;
-            List<PlcValue> value = new LinkedList<>();
-            while(readBuffer.getPos() < ${arrayField.name}EndPos) {
-                value.add(
-                <#if elementTypeReference.isSimpleTypeReference()>
-                    new 
${helper.getPlcValueTypeForTypeReference(elementTypeReference)}(${helper.getReadBufferReadMethodCall(elementTypeReference.asSimpleTypeReference().orElseThrow(),
 "", arrayField)})
-                
<#else>${elementTypeReference.asNonSimpleTypeReference().orElseThrow().name}IO.staticParse(readBuffer
-                    <#if elementTypeReference.params.isPresent()>,
-                        <#list elementTypeReference.params.orElseThrow() as 
parserArgument>
-                            
(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(elementTypeReference,
 parserArgument?index), true)}) (${helper.toParseExpression(arrayField, 
elementTypeReference, parserArgument,parserArguments)})
-                            <#sep>, </#sep>
-                        </#list>
-                    </#if>
-                    )
-                </#if>
-                );
-            }
-            <#-- A terminated array keeps on reading data as long as the 
termination expression evaluates to false -->
-                            <#elseif arrayField.isTerminatedArrayField()>
-            // Terminated array
-            ${helper.getNonPrimitiveLanguageTypeNameForField(arrayField)} 
${arrayField.name} = new LinkedList<>();
-            while(!((boolean) (${helper.toParseExpression(arrayField, 
helper.boolTypeReference, arrayField.loopExpression,parserArguments)}))) {
-                ${arrayField.name}.add(<#if 
elementTypeReference.isSimpleTypeReference()>${helper.getReadBufferReadMethodCall(elementTypeReference.asSimpleTypeReference().orElseThrow(),
 "", 
arrayField)}<#else>${elementTypeReference.asComplexTypeReference().orElseThrow().name}IO.staticParse(readBuffer<#if
 arrayField.params.isPresent()>, <#list arrayField.params.orElseThrow() as 
parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(elementTypeReference,
 parser [...]
+<#--    private static final Logger LOGGER = 
LoggerFactory.getLogger(${type.name}.class);-->
+<#--    public static PlcValue staticParse(ReadBuffer readBuffer<#if 
type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as 
parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type,
 false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) throws 
ParseException {-->
+<#--        <#assign defaultCaseOutput=false>-->
+<#--        <#assign 
dataIoTypeDefinition=type.asDataIoTypeDefinition().orElseThrow()>-->
+<#--        <#list dataIoTypeDefinition.switchField.orElseThrow().cases as 
case>-->
+<#--            <@compress single_line=true>-->
+<#--                <#if case.discriminatorValueTerms?has_content>-->
+<#--                    if(-->
+<#--                    <#list case.discriminatorValueTerms as 
discriminatorValueTerm>-->
+<#--                        <#assign 
discriminatorExpression=dataIoTypeDefinition.switchField.orElseThrow().discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow()>-->
+<#--                        <#assign 
discriminatorType=helper.getDiscriminatorTypes()[discriminatorExpression.name]>-->
+<#--                        EvaluationHelper.equals(-->
+<#--                        
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(), 
discriminatorType, discriminatorExpression, parserArguments)},-->
+<#--                        <#if discriminatorType.isEnumTypeReference()>-->
+<#--                        
${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
 discriminatorType, discriminatorValueTerm, parserArguments)}-->
+<#--                        <#else>-->
+<#--                        
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(), 
discriminatorType, discriminatorValueTerm, parserArguments)}-->
+<#--                        </#if>-->
+<#--                    )-->
+<#--                        <#sep> && </#sep>-->
+<#--                    </#list>-->
+<#--                    )-->
+<#--                <#else>-->
+<#--                    <#assign defaultCaseOutput=true>-->
+<#--                </#if>-->
+<#--            </@compress> { // ${case.name}-->
+<#--            <#assign valueDefined=false>-->
+<#--            <#list case.fields as field>-->
+<#--                <#switch field.typeName>-->
+<#--                    <#case "array">-->
+<#--                        <#assign arrayField = 
field.asArrayField().orElseThrow()>-->
+<#--                        <#assign 
elementTypeReference=arrayField.type.elementTypeReference>-->
+<#--            // Array field (${arrayField.name})-->
+<#--            &lt;#&ndash; Only update curPos if the length expression uses 
it &ndash;&gt;-->
+<#--                        <#if 
arrayField.loopExpression.contains("curPos")>-->
+<#--            curPos = readBuffer.getPos() - startPos;-->
+<#--                        </#if>-->
+<#--            &lt;#&ndash; If this is a count array, we can directly 
initialize an array with the given size &ndash;&gt;-->
+<#--                        <#if field.isCountArrayField()>-->
+<#--            // Count array-->
+<#--            if(${helper.toParseExpression(arrayField, 
helper.intTypeReference, arrayField.loopExpression,parserArguments)} > 
Integer.MAX_VALUE) {-->
+<#--                throw new ParseException("Array count of " + 
(${helper.toParseExpression(arrayField, helper.intTypeReference, 
arrayField.loopExpression,parserArguments)}) + " exceeds the maximum allowed 
count of " + Integer.MAX_VALUE);-->
+<#--            }-->
+<#--            List<PlcValue> ${arrayField.name};-->
+<#--            {-->
+<#--                int itemCount = (int) 
${helper.toParseExpression(arrayField, helper.intTypeReference, 
arrayField.loopExpression,parserArguments)};-->
+<#--                ${arrayField.name} = new LinkedList<>();-->
+<#--                for(int curItem = 0; curItem < itemCount; curItem++) {-->
+<#--                    ${arrayField.name}.add(new 
${helper.getPlcValueTypeForTypeReference(elementTypeReference)}((${helper.getLanguageTypeNameForTypeReference(elementTypeReference,
 false)}) <#if 
elementTypeReference.isSimpleTypeReference()>${helper.getReadBufferReadMethodCall(elementTypeReference.asSimpleTypeReference().orElseThrow(),
 "", 
arrayField)})<#else>${elementTypeReference.asComplexTypeReference().orElseThrow().name}IO.staticParse(readBuffer<#if
 elementTypeReference.params.isPr [...]
+<#--                }-->
+<#--            }-->
+<#--            &lt;#&ndash; In all other cases do we have to work with a 
list, that is later converted to an array &ndash;&gt;-->
+<#--                        <#else>-->
+<#--            &lt;#&ndash; For a length array, we read data till the read 
position of the buffer reaches a given position &ndash;&gt;-->
+<#--                            <#if arrayField.isLengthArrayField()>-->
+<#--            // Length array-->
+<#--            long _${arrayField.name}Length = 
${helper.toParseExpression(arrayField, helper.intTypeReference, 
arrayField.loopExpression,parserArguments)};-->
+<#--            long ${arrayField.name}EndPos = readBuffer.getPos() + 
_${arrayField.name}Length;-->
+<#--            List<PlcValue> value = new LinkedList<>();-->
+<#--            while(readBuffer.getPos() < ${arrayField.name}EndPos) {-->
+<#--                value.add(-->
+<#--                <#if elementTypeReference.isSimpleTypeReference()>-->
+<#--                    new 
${helper.getPlcValueTypeForTypeReference(elementTypeReference)}(${helper.getReadBufferReadMethodCall(elementTypeReference.asSimpleTypeReference().orElseThrow(),
 "", arrayField)})-->
+<#--                
<#else>${elementTypeReference.asNonSimpleTypeReference().orElseThrow().name}IO.staticParse(readBuffer-->
+<#--                    <#if elementTypeReference.params.isPresent()>,-->
+<#--                        <#list elementTypeReference.params.orElseThrow() 
as parserArgument>-->
+<#--                            
(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(elementTypeReference,
 parserArgument?index), true)}) (${helper.toParseExpression(arrayField, 
elementTypeReference, parserArgument,parserArguments)})-->
+<#--                            <#sep>, </#sep>-->
+<#--                        </#list>-->
+<#--                    </#if>-->
+<#--                    )-->
+<#--                </#if>-->
+<#--                );-->
+<#--            }-->
+<#--            &lt;#&ndash; A terminated array keeps on reading data as long 
as the termination expression evaluates to false &ndash;&gt;-->
+<#--                            <#elseif 
arrayField.isTerminatedArrayField()>-->
+<#--            // Terminated array-->
+<#--            ${helper.getNonPrimitiveLanguageTypeNameForField(arrayField)} 
${arrayField.name} = new LinkedList<>();-->
+<#--            while(!((boolean) (${helper.toParseExpression(arrayField, 
helper.boolTypeReference, arrayField.loopExpression,parserArguments)}))) {-->
+<#--                ${arrayField.name}.add(<#if 
elementTypeReference.isSimpleTypeReference()>${helper.getReadBufferReadMethodCall(elementTypeReference.asSimpleTypeReference().orElseThrow(),
 "", 
arrayField)}<#else>${elementTypeReference.asComplexTypeReference().orElseThrow().name}IO.staticParse(readBuffer<#if
 arrayField.params.isPresent()>, <#list arrayField.params.orElseThrow() as 
parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(elementTypeReference,
 pa [...]
 
-                <#-- After parsing, update the current position, but only if 
it's needed -->
-                                <#if 
arrayField.loopExpression.contains("curPos")>
-                curPos = readBuffer.getPos() - startPos;
-                                </#if>
-            }
-                            </#if>
-                        </#if>
-                        <#if arrayField.name == "value">
-                            <#assign valueDefined=true>
-                        </#if>
-                    <#break>
-                    <#case "const">
-                        <#assign constField=field.asConstField().orElseThrow()>
+<#--                &lt;#&ndash; After parsing, update the current position, 
but only if it's needed &ndash;&gt;-->
+<#--                                <#if 
arrayField.loopExpression.contains("curPos")>-->
+<#--                curPos = readBuffer.getPos() - startPos;-->
+<#--                                </#if>-->
+<#--            }-->
+<#--                            </#if>-->
+<#--                        </#if>-->
+<#--                        <#if arrayField.name == "value">-->
+<#--                            <#assign valueDefined=true>-->
+<#--                        </#if>-->
+<#--                    <#break>-->
+<#--                    <#case "const">-->
+<#--                        <#assign 
constField=field.asConstField().orElseThrow()>-->
 
-            // Const Field (${constField.name})
-            ${helper.getNonPrimitiveLanguageTypeNameForField(constField)} 
${constField.name} = 
${helper.getReadBufferReadMethodCall(constField.type.asSimpleTypeReference().orElseThrow(),
 "", constField)};
-            if(${constField.name} != 
${dataIoTypeDefinition.name}.${constField.name?upper_case}) {
-                throw new ParseException("Expected constant value " + 
${dataIoTypeDefinition.name}.${constField.name?upper_case} + " but got " + 
${constField.name});
-            }
-                        <#if constField.name == "value">
-                            <#assign valueDefined=true>
-                        </#if>
-                    <#break>
-                    <#case "enum">
-                        <#assign enumField=field.asEnumField().orElseThrow()>
+<#--            // Const Field (${constField.name})-->
+<#--            ${helper.getNonPrimitiveLanguageTypeNameForField(constField)} 
${constField.name} = 
${helper.getReadBufferReadMethodCall(constField.type.asSimpleTypeReference().orElseThrow(),
 "", constField)};-->
+<#--            if(${constField.name} != 
${dataIoTypeDefinition.name}.${constField.name?upper_case}) {-->
+<#--                throw new ParseException("Expected constant value " + 
${dataIoTypeDefinition.name}.${constField.name?upper_case} + " but got " + 
${constField.name});-->
+<#--            }-->
+<#--                        <#if constField.name == "value">-->
+<#--                            <#assign valueDefined=true>-->
+<#--                        </#if>-->
+<#--                    <#break>-->
+<#--                    <#case "enum">-->
+<#--                        <#assign 
enumField=field.asEnumField().orElseThrow()>-->
 
-            // Enum field (${enumField.name})
-            ${helper.getNonPrimitiveLanguageTypeNameForField(enumField)} 
${enumField.name} = 
${helper.getNonPrimitiveLanguageTypeNameForField(enumField)}.enumForValue(${helper.getReadBufferReadMethodCall(helper.getEnumBaseTypeReference(enumField.type.asSimpleTypeReference().orElseThrow()),
 "", enumField)});
-                        <#if enumField.name == "value">
-                            <#assign valueDefined=true>
-                        </#if>
-                    <#break>
-                    <#case "manual">
-                        <#assign 
manualField=field.asManualField().orElseThrow()>
+<#--            // Enum field (${enumField.name})-->
+<#--            ${helper.getNonPrimitiveLanguageTypeNameForField(enumField)} 
${enumField.name} = 
${helper.getNonPrimitiveLanguageTypeNameForField(enumField)}.enumForValue(${helper.getReadBufferReadMethodCall(helper.getEnumBaseTypeReference(enumField.type.asSimpleTypeReference().orElseThrow()),
 "", enumField)});-->
+<#--                        <#if enumField.name == "value">-->
+<#--                            <#assign valueDefined=true>-->
+<#--                        </#if>-->
+<#--                    <#break>-->
+<#--                    <#case "manual">-->
+<#--                        <#assign 
manualField=field.asManualField().orElseThrow()>-->
 
-            // Manual Field (${manualField.name})
-            ${helper.getLanguageTypeNameForField(field)} ${manualField.name} = 
(${helper.getLanguageTypeNameForField(manualField)}) 
(${helper.toParseExpression(manualField, manualField.type, 
manualField.parseExpression,parserArguments)});
-                        <#if manualField.name == "value">
-                            <#assign valueDefined=true>
-                        </#if>
-                    <#break>
-                    <#case "reserved">
-                        <#assign 
reservedField=field.asReservedField().orElseThrow()>
+<#--            // Manual Field (${manualField.name})-->
+<#--            ${helper.getLanguageTypeNameForField(field)} 
${manualField.name} = (${helper.getLanguageTypeNameForField(manualField)}) 
(${helper.toParseExpression(manualField, manualField.type, 
manualField.parseExpression,parserArguments)});-->
+<#--                        <#if manualField.name == "value">-->
+<#--                            <#assign valueDefined=true>-->
+<#--                        </#if>-->
+<#--                    <#break>-->
+<#--                    <#case "reserved">-->
+<#--                        <#assign 
reservedField=field.asReservedField().orElseThrow()>-->
 
-            // Reserved Field (Compartmentalized so the "reserved" variable 
can't leak)
-            {
-                ${helper.getLanguageTypeNameForField(field)} reserved = 
${helper.getReadBufferReadMethodCall(reservedField.type.asSimpleTypeReference().orElseThrow(),
 "", reservedField)};
-                if(reserved != ${helper.getReservedValue(reservedField)}) {
-                    LOGGER.info("Expected constant value " + 
${reservedField.referenceValue} + " but got " + reserved + " for reserved 
field.");
-                }
-            }
-                    <#break>
-                    <#case "simple">
-                        <#assign 
simpleField=field.asSimpleField().orElseThrow()>
+<#--            // Reserved Field (Compartmentalized so the "reserved" 
variable can't leak)-->
+<#--            {-->
+<#--                ${helper.getLanguageTypeNameForField(field)} reserved = 
${helper.getReadBufferReadMethodCall(reservedField.type.asSimpleTypeReference().orElseThrow(),
 "", reservedField)};-->
+<#--                if(reserved != ${helper.getReservedValue(reservedField)}) 
{-->
+<#--                    LOGGER.info("Expected constant value " + 
${reservedField.referenceValue} + " but got " + reserved + " for reserved 
field.");-->
+<#--                }-->
+<#--            }-->
+<#--                    <#break>-->
+<#--                    <#case "simple">-->
+<#--                        <#assign 
simpleField=field.asSimpleField().orElseThrow()>-->
 
-                        <#if helper.isEnumField(simpleField)>
-            // Enum field (${simpleField.name})
-            ${helper.getNonPrimitiveLanguageTypeNameForField(simpleField)} 
${simpleField.name} = 
${helper.getNonPrimitiveLanguageTypeNameForField(simpleField)}.enumForValue(${helper.getReadBufferReadMethodCall(helper.getEnumBaseTypeReference(simpleField.type),
 "", simpleField)});
-                        <#else>
-            // Simple Field (${simpleField.name})
-            ${helper.getNonPrimitiveLanguageTypeNameForField(simpleField)} 
${simpleField.name} = <#if 
simpleField.type.isSimpleTypeReference()>${helper.getReadBufferReadMethodCall(simpleField.type.asSimpleTypeReference().orElseThrow(),
 "", 
simpleField)}<#else>${simpleField.type.asComplexTypeReference().orElseThrow().name}IO.staticParse(readBuffer<#if
 simpleField.params.isPresent()>, <#list field.params.orElseThrow() as 
parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.g [...]
-                        </#if>
-                        <#if case.name == "Struct" ||
-                            ((case.name == "DATE_AND_TIME") && 
((simpleField.name == "year") || (simpleField.name == "month") || 
(simpleField.name == "day") || (simpleField.name == "hour") || 
(simpleField.name == "minutes") || (simpleField.name == "seconds"))) ||
-                            ((case.name == "DATE_AND_TIME") && 
(simpleField.name == "secondsSinceEpoch")) ||
-                            ((case.name == "DATE") && ((simpleField.name == 
"year") || (simpleField.name == "month") || (simpleField.name == "day"))) ||
-                            ((case.name == "TIME_OF_DAY") && 
((simpleField.name == "hour") || (simpleField.name == "minutes") || 
(simpleField.name == "seconds"))) ||
-                        simpleField.name == "value">
-                            <#assign valueDefined=true>
-                        </#if>
-                    <#break>
-                </#switch>
-            </#list>
-            <#if case.name == "Struct">
+<#--                        <#if helper.isEnumField(simpleField)>-->
+<#--            // Enum field (${simpleField.name})-->
+<#--            ${helper.getNonPrimitiveLanguageTypeNameForField(simpleField)} 
${simpleField.name} = 
${helper.getNonPrimitiveLanguageTypeNameForField(simpleField)}.enumForValue(${helper.getReadBufferReadMethodCall(helper.getEnumBaseTypeReference(simpleField.type),
 "", simpleField)});-->
+<#--                        <#else>-->
+<#--            // Simple Field (${simpleField.name})-->
+<#--            ${helper.getNonPrimitiveLanguageTypeNameForField(simpleField)} 
${simpleField.name} = <#if 
simpleField.type.isSimpleTypeReference()>${helper.getReadBufferReadMethodCall(simpleField.type.asSimpleTypeReference().orElseThrow(),
 "", 
simpleField)}<#else>${simpleField.type.asComplexTypeReference().orElseThrow().name}IO.staticParse(readBuffer<#if
 simpleField.params.isPresent()>, <#list field.params.orElseThrow() as 
parserArgument>(${helper.getLanguageTypeNameForTypeReference(help [...]
+<#--                        </#if>-->
+<#--                        <#if case.name == "Struct" ||-->
+<#--                            ((case.name == "DATE_AND_TIME") && 
((simpleField.name == "year") || (simpleField.name == "month") || 
(simpleField.name == "day") || (simpleField.name == "hour") || 
(simpleField.name == "minutes") || (simpleField.name == "seconds"))) ||-->
+<#--                            ((case.name == "DATE_AND_TIME") && 
(simpleField.name == "secondsSinceEpoch")) ||-->
+<#--                            ((case.name == "DATE") && ((simpleField.name 
== "year") || (simpleField.name == "month") || (simpleField.name == "day"))) 
||-->
+<#--                            ((case.name == "TIME_OF_DAY") && 
((simpleField.name == "hour") || (simpleField.name == "minutes") || 
(simpleField.name == "seconds"))) ||-->
+<#--                        simpleField.name == "value">-->
+<#--                            <#assign valueDefined=true>-->
+<#--                        </#if>-->
+<#--                    <#break>-->
+<#--                </#switch>-->
+<#--            </#list>-->
+<#--            <#if case.name == "Struct">-->
 
-                <#-- In this case we need to wrap each field in a PlcValue 
that matches it's natural type -->
-            Map<String, PlcValue> _map = new HashMap<>();
-                <#list case.fields as field>
-                    <#if field.isArrayField()>
-                        <#assign field=field.asArrayField().orElseThrow()>
-            _map.put("${field.name}", new PlcList(${field.name}));
-                    <#elseif field.isPropertyField()>
-                        <#assign field=field.asPropertyField().orElseThrow()>
-                        <#switch 
helper.getLanguageTypeNameForTypeReference(field.type)>
-                            <#case "Boolean">
-            _map.put("${field.name}", new PlcBOOL(${field.name}));
-                                <#break>
-                            <#case "Byte">
-            _map.put("${field.name}", new PlcSINT(${field.name}));
-                                <#break>
-                            <#case "Short">
-            _map.put("${field.name}", new PlcINT(${field.name}));
-                                <#break>
-                            <#case "Integer">
-            _map.put("${field.name}", new PlcDINT(${field.name}));
-                                <#break>
-                            <#case "Long">
-            _map.put("${field.name}", new PlcLINT(${field.name}));
-                                <#break>
-                            <#case "BigInteger">
-            _map.put("${field.name}", new PlcBigInteger(${field.name}));
-                                <#break>
-                            <#case "Float">
-            _map.put("${field.name}", new PlcREAL(${field.name}));
-                                <#break>
-                            <#case "Double">
-            _map.put("${field.name}", new PlcLREAL(${field.name}));
-                                <#break>
-                            <#case "BigDecimal">
-            _map.put("${field.name}", new PlcBigDecimal(${field.name}));
-                                <#break>
-                            <#case "String">
-            _map.put("${field.name}", new PlcSTRING(${field.name}));
-                                <#break>
-                            <#case "LocalTime">
-            _map.put("${field.name}", new PlcTIME_OF_DAY(${field.name}));
-                                <#break>
-                            <#case "LocalDate">
-            _map.put("${field.name}", new PlcDATE(${field.name}));
-                                <#break>
-                            <#case "LocalDateTime">
-            _map.put("${field.name}", new PlcDATE_AND_TIME(${field.name}));
-                                <#break>
-                        </#switch>
-                    </#if>
-                </#list>
-                <#assign valueDefined=true>
-            </#if>
+<#--                &lt;#&ndash; In this case we need to wrap each field in a 
PlcValue that matches it's natural type &ndash;&gt;-->
+<#--            Map<String, PlcValue> _map = new HashMap<>();-->
+<#--                <#list case.fields as field>-->
+<#--                    <#if field.isArrayField()>-->
+<#--                        <#assign 
field=field.asArrayField().orElseThrow()>-->
+<#--            _map.put("${field.name}", new PlcList(${field.name}));-->
+<#--                    <#elseif field.isPropertyField()>-->
+<#--                        <#assign 
field=field.asPropertyField().orElseThrow()>-->
+<#--                        <#switch 
helper.getLanguageTypeNameForTypeReference(field.type)>-->
+<#--                            <#case "Boolean">-->
+<#--            _map.put("${field.name}", new PlcBOOL(${field.name}));-->
+<#--                                <#break>-->
+<#--                            <#case "Byte">-->
+<#--            _map.put("${field.name}", new PlcSINT(${field.name}));-->
+<#--                                <#break>-->
+<#--                            <#case "Short">-->
+<#--            _map.put("${field.name}", new PlcINT(${field.name}));-->
+<#--                                <#break>-->
+<#--                            <#case "Integer">-->
+<#--            _map.put("${field.name}", new PlcDINT(${field.name}));-->
+<#--                                <#break>-->
+<#--                            <#case "Long">-->
+<#--            _map.put("${field.name}", new PlcLINT(${field.name}));-->
+<#--                                <#break>-->
+<#--                            <#case "BigInteger">-->
+<#--            _map.put("${field.name}", new PlcBigInteger(${field.name}));-->
+<#--                                <#break>-->
+<#--                            <#case "Float">-->
+<#--            _map.put("${field.name}", new PlcREAL(${field.name}));-->
+<#--                                <#break>-->
+<#--                            <#case "Double">-->
+<#--            _map.put("${field.name}", new PlcLREAL(${field.name}));-->
+<#--                                <#break>-->
+<#--                            <#case "BigDecimal">-->
+<#--            _map.put("${field.name}", new PlcBigDecimal(${field.name}));-->
+<#--                                <#break>-->
+<#--                            <#case "String">-->
+<#--            _map.put("${field.name}", new PlcSTRING(${field.name}));-->
+<#--                                <#break>-->
+<#--                            <#case "LocalTime">-->
+<#--            _map.put("${field.name}", new 
PlcTIME_OF_DAY(${field.name}));-->
+<#--                                <#break>-->
+<#--                            <#case "LocalDate">-->
+<#--            _map.put("${field.name}", new PlcDATE(${field.name}));-->
+<#--                                <#break>-->
+<#--                            <#case "LocalDateTime">-->
+<#--            _map.put("${field.name}", new 
PlcDATE_AND_TIME(${field.name}));-->
+<#--                                <#break>-->
+<#--                        </#switch>-->
+<#--                    </#if>-->
+<#--                </#list>-->
+<#--                <#assign valueDefined=true>-->
+<#--            </#if>-->
 
-            <#if valueDefined>
-                <#switch case.name>
-                    <#case "TIME">
-            return new PlcTIME(value);
-                    <#break>
-                    <#case "DATE">
-                    <#if helper.hasFieldsWithNames(case.fields, "year", 
"month", "day")>
-            LocalDate value = LocalDate.of(year.intValue(), (month == 0) ? 1 : 
month.intValue(), (day == 0) ? 1 : day.intValue());
-                    </#if>
-            return new PlcDATE(value);
-                    <#break>
-                    <#case "TIME_OF_DAY">
-                    <#if helper.hasFieldsWithNames(case.fields, "hour", 
"minutes", "seconds", "nanos")>
-            LocalTime value = LocalTime.of(hour.intValue(), 
minutes.intValue(), seconds.intValue(), nanos.intValue());
-                    <#elseif helper.hasFieldsWithNames(case.fields, "hour", 
"minutes", "seconds")>
-            LocalTime value = LocalTime.of(hour.intValue(), 
minutes.intValue(), seconds.intValue());
-                    </#if>
-            return new PlcTIME_OF_DAY(value);
-                    <#break>
-                    <#case "DATE_AND_TIME">
-                    <#if helper.hasFieldsWithNames(case.fields, "year", 
"month", "day", "hour", "minutes", "seconds", "nanos")>
-            LocalDateTime value = LocalDateTime.of(year.intValue(), (month == 
0) ? 1 : month.intValue(), (day == 0) ? 1 : day.intValue(), hour.intValue(), 
minutes.intValue(), seconds.intValue(), nanos.intValue());
-                    <#elseif helper.hasFieldsWithNames(case.fields, "year", 
"month", "day", "hour", "minutes", "seconds")>
-            LocalDateTime value = LocalDateTime.of(year.intValue(), (month == 
0) ? 1 : month.intValue(), (day == 0) ? 1 : day.intValue(), hour.intValue(), 
minutes.intValue(), seconds.intValue());
-                    <#elseif helper.hasFieldsWithNames(case.fields, 
"secondsSinceEpoch")>
-            LocalDateTime value = 
LocalDateTime.ofEpochSecond(secondsSinceEpoch, 0, ZoneOffset.UTC);
-                    </#if>
-            return new PlcDATE_AND_TIME(value);
-                    <#break>
-                    <#case "Struct">
-            return new PlcStruct(_map);
-                    <#break>
-                    <#case "List">
-            return new PlcList(value);
-                    <#break>
-                    <#default>
-            return new Plc${case.name}(value);
-                </#switch>
-            </#if>
-        }<#sep> else </#sep></#list>
-        <#if !defaultCaseOutput>
-        return null;
-        </#if>
-    }
+<#--            <#if valueDefined>-->
+<#--                <#switch case.name>-->
+<#--                    <#case "TIME">-->
+<#--            return new PlcTIME(value);-->
+<#--                    <#break>-->
+<#--                    <#case "DATE">-->
+<#--                    <#if helper.hasFieldsWithNames(case.fields, "year", 
"month", "day")>-->
+<#--            LocalDate value = LocalDate.of(year.intValue(), (month == 0) ? 
1 : month.intValue(), (day == 0) ? 1 : day.intValue());-->
+<#--                    </#if>-->
+<#--            return new PlcDATE(value);-->
+<#--                    <#break>-->
+<#--                    <#case "TIME_OF_DAY">-->
+<#--                    <#if helper.hasFieldsWithNames(case.fields, "hour", 
"minutes", "seconds", "nanos")>-->
+<#--            LocalTime value = LocalTime.of(hour.intValue(), 
minutes.intValue(), seconds.intValue(), nanos.intValue());-->
+<#--                    <#elseif helper.hasFieldsWithNames(case.fields, 
"hour", "minutes", "seconds")>-->
+<#--            LocalTime value = LocalTime.of(hour.intValue(), 
minutes.intValue(), seconds.intValue());-->
+<#--                    </#if>-->
+<#--            return new PlcTIME_OF_DAY(value);-->
+<#--                    <#break>-->
+<#--                    <#case "DATE_AND_TIME">-->
+<#--                    <#if helper.hasFieldsWithNames(case.fields, "year", 
"month", "day", "hour", "minutes", "seconds", "nanos")>-->
+<#--            LocalDateTime value = LocalDateTime.of(year.intValue(), (month 
== 0) ? 1 : month.intValue(), (day == 0) ? 1 : day.intValue(), hour.intValue(), 
minutes.intValue(), seconds.intValue(), nanos.intValue());-->
+<#--                    <#elseif helper.hasFieldsWithNames(case.fields, 
"year", "month", "day", "hour", "minutes", "seconds")>-->
+<#--            LocalDateTime value = LocalDateTime.of(year.intValue(), (month 
== 0) ? 1 : month.intValue(), (day == 0) ? 1 : day.intValue(), hour.intValue(), 
minutes.intValue(), seconds.intValue());-->
+<#--                    <#elseif helper.hasFieldsWithNames(case.fields, 
"secondsSinceEpoch")>-->
+<#--            LocalDateTime value = 
LocalDateTime.ofEpochSecond(secondsSinceEpoch, 0, ZoneOffset.UTC);-->
+<#--                    </#if>-->
+<#--            return new PlcDATE_AND_TIME(value);-->
+<#--                    <#break>-->
+<#--                    <#case "Struct">-->
+<#--            return new PlcStruct(_map);-->
+<#--                    <#break>-->
+<#--                    <#case "List">-->
+<#--            return new PlcList(value);-->
+<#--                    <#break>-->
+<#--                    <#default>-->
+<#--            return new Plc${case.name}(value);-->
+<#--                </#switch>-->
+<#--            </#if>-->
+<#--        }<#sep> else </#sep></#list>-->
+<#--        <#if !defaultCaseOutput>-->
+<#--        return null;-->
+<#--        </#if>-->
+<#--    }-->
 
-<#if outputFlavor != "passive">
-    public static void staticSerialize(WriteBuffer writeBuffer, PlcValue 
_value<#if type.parserArguments.isPresent()>, <#list 
type.parserArguments.orElseThrow() as 
parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type,
 false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) throws 
SerializationException {
-        staticSerialize(writeBuffer, _value<#if 
type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as 
parserArgument>${parserArgument.name}<#sep>, </#sep></#list></#if>, 
ByteOrder.BIG_ENDIAN);
-    }
+<#--<#if outputFlavor != "passive">-->
+<#--    public static void staticSerialize(WriteBuffer writeBuffer, PlcValue 
_value<#if type.parserArguments.isPresent()>, <#list 
type.parserArguments.orElseThrow() as 
parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type,
 false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) throws 
SerializationException {-->
+<#--        staticSerialize(writeBuffer, _value<#if 
type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as 
parserArgument>${parserArgument.name}<#sep>, </#sep></#list></#if>, 
ByteOrder.BIG_ENDIAN);-->
+<#--    }-->
 
-    public static void staticSerialize(WriteBuffer writeBuffer, PlcValue 
_value<#if type.parserArguments.isPresent()>, <#list 
type.parserArguments.orElseThrow() as 
parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type,
 false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>, ByteOrder 
byteOrder) throws SerializationException {
-        <#assign defaultCaseOutput=false>
-        <#assign 
dataIoTypeDefinition=type.asDataIoTypeDefinition().orElseThrow()>
-        <#list dataIoTypeDefinition.switchField.orElseThrow().cases as case>
-        <@compress single_line=true>
-            <#if case.discriminatorValueTerms?has_content>
-                if(
-                <#list case.discriminatorValueTerms as discriminatorValueTerm>
-                    <#assign 
discriminatorExpression=dataIoTypeDefinition.switchField.orElseThrow().discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow()>
-                    <#assign 
discriminatorType=helper.getDiscriminatorTypes()[discriminatorExpression.name]>
-                    EvaluationHelper.equals(
-                    
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(), 
discriminatorType, discriminatorExpression, parserArguments)},
-                    <#if discriminatorType.isEnumTypeReference()>
-                    
${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
 discriminatorType, discriminatorValueTerm, parserArguments)}
-                    <#else>
-                    
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(), 
discriminatorType, discriminatorValueTerm, parserArguments)}
-                    </#if>
-                    )
-                    <#sep> && </#sep>
-                </#list>
-                )
-            <#else>
-                <#assign defaultCaseOutput=true>
-            </#if>
-        </@compress> { // ${case.name}
-            <#list case.fields as field>
-                <#switch field.typeName>
-                    <#case "array">
-                        <#assign arrayField=field.asArrayField().orElseThrow()>
-                        <#assign 
elementTypeReference=arrayField.type.elementTypeReference>
-            PlcList values = (PlcList) _value;
+<#--    public static void staticSerialize(WriteBuffer writeBuffer, PlcValue 
_value<#if type.parserArguments.isPresent()>, <#list 
type.parserArguments.orElseThrow() as 
parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type,
 false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>, ByteOrder 
byteOrder) throws SerializationException {-->
+<#--        <#assign defaultCaseOutput=false>-->
+<#--        <#assign 
dataIoTypeDefinition=type.asDataIoTypeDefinition().orElseThrow()>-->
+<#--        <#list dataIoTypeDefinition.switchField.orElseThrow().cases as 
case>-->
+<#--        <@compress single_line=true>-->
+<#--            <#if case.discriminatorValueTerms?has_content>-->
+<#--                if(-->
+<#--                <#list case.discriminatorValueTerms as 
discriminatorValueTerm>-->
+<#--                    <#assign 
discriminatorExpression=dataIoTypeDefinition.switchField.orElseThrow().discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow()>-->
+<#--                    <#assign 
discriminatorType=helper.getDiscriminatorTypes()[discriminatorExpression.name]>-->
+<#--                    EvaluationHelper.equals(-->
+<#--                    
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(), 
discriminatorType, discriminatorExpression, parserArguments)},-->
+<#--                    <#if discriminatorType.isEnumTypeReference()>-->
+<#--                    
${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
 discriminatorType, discriminatorValueTerm, parserArguments)}-->
+<#--                    <#else>-->
+<#--                    
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(), 
discriminatorType, discriminatorValueTerm, parserArguments)}-->
+<#--                    </#if>-->
+<#--                    )-->
+<#--                    <#sep> && </#sep>-->
+<#--                </#list>-->
+<#--                )-->
+<#--            <#else>-->
+<#--                <#assign defaultCaseOutput=true>-->
+<#--            </#if>-->
+<#--        </@compress> { // ${case.name}-->
+<#--            <#list case.fields as field>-->
+<#--                <#switch field.typeName>-->
+<#--                    <#case "array">-->
+<#--                        <#assign 
arrayField=field.asArrayField().orElseThrow()>-->
+<#--                        <#assign 
elementTypeReference=arrayField.type.elementTypeReference>-->
+<#--            PlcList values = (PlcList) _value;-->
 
-                        <#if case.name == "Struct">
-            for (PlcValue val : ((List<PlcValue>) 
values.getStruct().get("${arrayField.name}").getList())) {
-                <#if elementTypeReference.isByteBased()>
-                ${helper.getLanguageTypeNameForField(arrayField)} value = 
(${helper.getLanguageTypeNameForField(arrayField)}) val.getRaw();
-                writeBuffer.writeByteArray("", value);
-                <#else>
-                ${helper.getLanguageTypeNameForField(arrayField)} value = 
(${helper.getLanguageTypeNameForField(arrayField)}) 
val.get${helper.getLanguageTypeNameForField(arrayField)?cap_first}();
-                
${helper.getWriteBufferWriteMethodCall(elementTypeReference.asSimpleTypeReference().orElseThrow(),
 "value", arrayField)};
-                </#if>
-            }
-                        <#else>
-            for (PlcValue val : ((List<PlcValue>) values.getList())) {
-                <#if elementTypeReference.isByteBased()>
-                byte[] value = (byte[]) val.getRaw();
-                writeBuffer.writeByteArray("", value);
-                <#else>
-                
${helper.getLanguageTypeNameForTypeReference(elementTypeReference)} value = 
(${helper.getLanguageTypeNameForTypeReference(elementTypeReference)}) 
val.get${helper.getLanguageTypeNameForTypeReference(elementTypeReference)?cap_first}();
-                
${helper.getWriteBufferWriteMethodCall(elementTypeReference.asSimpleTypeReference().orElseThrow(),
 "(" + arrayField.name + ")", arrayField)};
-                </#if>
-            }
-                        </#if>
+<#--                        <#if case.name == "Struct">-->
+<#--            for (PlcValue val : ((List<PlcValue>) 
values.getStruct().get("${arrayField.name}").getList())) {-->
+<#--                <#if elementTypeReference.isByteBased()>-->
+<#--                ${helper.getLanguageTypeNameForField(arrayField)} value = 
(${helper.getLanguageTypeNameForField(arrayField)}) val.getRaw();-->
+<#--                writeBuffer.writeByteArray("", value);-->
+<#--                <#else>-->
+<#--                ${helper.getLanguageTypeNameForField(arrayField)} value = 
(${helper.getLanguageTypeNameForField(arrayField)}) 
val.get${helper.getLanguageTypeNameForField(arrayField)?cap_first}();-->
+<#--                
${helper.getWriteBufferWriteMethodCall(elementTypeReference.asSimpleTypeReference().orElseThrow(),
 "value", arrayField)};-->
+<#--                </#if>-->
+<#--            }-->
+<#--                        <#else>-->
+<#--            for (PlcValue val : ((List<PlcValue>) values.getList())) {-->
+<#--                <#if elementTypeReference.isByteBased()>-->
+<#--                byte[] value = (byte[]) val.getRaw();-->
+<#--                writeBuffer.writeByteArray("", value);-->
+<#--                <#else>-->
+<#--                
${helper.getLanguageTypeNameForTypeReference(elementTypeReference)} value = 
(${helper.getLanguageTypeNameForTypeReference(elementTypeReference)}) 
val.get${helper.getLanguageTypeNameForTypeReference(elementTypeReference)?cap_first}();-->
+<#--                
${helper.getWriteBufferWriteMethodCall(elementTypeReference.asSimpleTypeReference().orElseThrow(),
 "(" + arrayField.name + ")", arrayField)};-->
+<#--                </#if>-->
+<#--            }-->
+<#--                        </#if>-->
 
-                    <#if case.name == "BOOL">
-            while (writeBuffer.getPos() < writeBuffer.getData().length) {
-                writeBuffer.writeBit(false);
-            }
-                    </#if>
-                    <#break>
-                    <#case "const">
-                        <#assign constField=field.asConstField().orElseThrow()>
-            // Const Field (${constField.name})
-            
${helper.getWriteBufferWriteMethodCall(constField.type.asSimpleTypeReference().orElseThrow(),
 constField.referenceValue, constField)};
-                    <#break>
-                    <#case "enum">
-                        <#assign enumField=field.asEnumField().orElseThrow()>
-            // Enum field (${enumField.name})
-            ${helper.getLanguageTypeNameForField(field)} ${enumField.name} = 
(${helper.getLanguageTypeNameForField(field)}) 
_value.get${enumField.name?cap_first}();
-            
${helper.getWriteBufferWriteMethodCall(helper.getEnumBaseTypeReference(field.asTypedField().orElseThrow().type),
 "(" + enumField.name + ".getValue())", enumField)};
-                    <#break>
-                    <#case "manual">
-                        <#assign 
manualField=field.asManualField().orElseThrow()>
-            // Manual Field (${manualField.name})
-            ${helper.toSerializationExpression(manualField, manualField.type, 
manualField.serializeExpression, type.parserArguments.orElse(null))};
-                    <#break>
-                    <#case "reserved">
-                        <#assign 
reservedField=field.asReservedField().orElseThrow()>
-            // Reserved Field
-            
${helper.getWriteBufferWriteMethodCall(reservedField.type.asSimpleTypeReference().orElseThrow(),
 helper.getReservedValue(reservedField), reservedField)};
-                    <#break>
-                    <#case "simple">
-                        <#assign 
simpleField=field.asSimpleField().orElseThrow()>
-            // Simple Field (${simpleField.name})
-                        <#if case.name == "Struct">
-            ${helper.getLanguageTypeNameForField(simpleField)} 
${simpleField.name} = (${helper.getLanguageTypeNameForField(field)}) 
_value.getStruct().get("${simpleField.name}").get${helper.getLanguageTypeNameForField(simpleField)?cap_first}();
-                        <#else>
-                            <#if simpleField.name == "value">
-            ${helper.getLanguageTypeNameForField(simpleField)} 
${simpleField.name} = (${helper.getLanguageTypeNameForField(field)}) 
_value.get${helper.getLanguageTypeNameForField(simpleField)?cap_first}();
-                            <#else>
-                                <#-- Just for now -->
-            ${helper.getLanguageTypeNameForField(simpleField)} 
${simpleField.name} = ${helper.getNullValueForTypeReference(simpleField.type)};
-                            </#if>
-                        </#if>
-                        <#if simpleField.type.isSimpleTypeReference()>
-            
${helper.getWriteBufferWriteMethodCall(simpleField.type.asSimpleTypeReference().orElseThrow(),
 "(" + simpleField.name + ")", simpleField)};
-                        <#else>
-            
${simpleField.type.asComplexTypeReference().orElseThrow().name}IO.staticSerialize(writeBuffer,
 ${simpleField.name});
-                        </#if>
-                    <#break>
-                </#switch>
-            </#list>
-        }<#sep> else </#sep></#list>
-    }
-</#if>
+<#--                    <#if case.name == "BOOL">-->
+<#--            while (writeBuffer.getPos() < writeBuffer.getData().length) 
{-->
+<#--                writeBuffer.writeBit(false);-->
+<#--            }-->
+<#--                    </#if>-->
+<#--                    <#break>-->
+<#--                    <#case "const">-->
+<#--                        <#assign 
constField=field.asConstField().orElseThrow()>-->
+<#--            // Const Field (${constField.name})-->
+<#--            
${helper.getWriteBufferWriteMethodCall(constField.type.asSimpleTypeReference().orElseThrow(),
 constField.referenceValue, constField)};-->
+<#--                    <#break>-->
+<#--                    <#case "enum">-->
+<#--                        <#assign 
enumField=field.asEnumField().orElseThrow()>-->
+<#--            // Enum field (${enumField.name})-->
+<#--            ${helper.getLanguageTypeNameForField(field)} ${enumField.name} 
= (${helper.getLanguageTypeNameForField(field)}) 
_value.get${enumField.name?cap_first}();-->
+<#--            
${helper.getWriteBufferWriteMethodCall(helper.getEnumBaseTypeReference(field.asTypedField().orElseThrow().type),
 "(" + enumField.name + ".getValue())", enumField)};-->
+<#--                    <#break>-->
+<#--                    <#case "manual">-->
+<#--                        <#assign 
manualField=field.asManualField().orElseThrow()>-->
+<#--            // Manual Field (${manualField.name})-->
+<#--            ${helper.toSerializationExpression(manualField, 
manualField.type, manualField.serializeExpression, 
type.parserArguments.orElse(null))};-->
+<#--                    <#break>-->
+<#--                    <#case "reserved">-->
+<#--                        <#assign 
reservedField=field.asReservedField().orElseThrow()>-->
+<#--            // Reserved Field-->
+<#--            
${helper.getWriteBufferWriteMethodCall(reservedField.type.asSimpleTypeReference().orElseThrow(),
 helper.getReservedValue(reservedField), reservedField)};-->
+<#--                    <#break>-->
+<#--                    <#case "simple">-->
+<#--                        <#assign 
simpleField=field.asSimpleField().orElseThrow()>-->
+<#--            // Simple Field (${simpleField.name})-->
+<#--                        <#if case.name == "Struct">-->
+<#--            ${helper.getLanguageTypeNameForField(simpleField)} 
${simpleField.name} = (${helper.getLanguageTypeNameForField(field)}) 
_value.getStruct().get("${simpleField.name}").get${helper.getLanguageTypeNameForField(simpleField)?cap_first}();-->
+<#--                        <#else>-->
+<#--                            <#if simpleField.name == "value">-->
+<#--            ${helper.getLanguageTypeNameForField(simpleField)} 
${simpleField.name} = (${helper.getLanguageTypeNameForField(field)}) 
_value.get${helper.getLanguageTypeNameForField(simpleField)?cap_first}();-->
+<#--                            <#else>-->
+<#--                                &lt;#&ndash; Just for now &ndash;&gt;-->
+<#--            ${helper.getLanguageTypeNameForField(simpleField)} 
${simpleField.name} = 
${helper.getNullValueForTypeReference(simpleField.type)};-->
+<#--                            </#if>-->
+<#--                        </#if>-->
+<#--                        <#if simpleField.type.isSimpleTypeReference()>-->
+<#--            
${helper.getWriteBufferWriteMethodCall(simpleField.type.asSimpleTypeReference().orElseThrow(),
 "(" + simpleField.name + ")", simpleField)};-->
+<#--                        <#else>-->
+<#--            
${simpleField.type.asComplexTypeReference().orElseThrow().name}IO.staticSerialize(writeBuffer,
 ${simpleField.name});-->
+<#--                        </#if>-->
+<#--                    <#break>-->
+<#--                </#switch>-->
+<#--            </#list>-->
+<#--        }<#sep> else </#sep></#list>-->
+<#--    }-->
+<#--</#if>-->
 
-    public static int getLengthInBytes(PlcValue _value<#if 
type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as 
parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type,
 false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) {
-        return (int) Math.ceil((float) getLengthInBits(_value<#if 
type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as 
parserArgument>${parserArgument.name}<#sep>, </#sep></#list></#if>) / 8.0);
-    }
+<#--    public static int getLengthInBytes(PlcValue _value<#if 
type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as 
parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type,
 false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) {-->
+<#--        return (int) Math.ceil((float) getLengthInBits(_value<#if 
type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as 
parserArgument>${parserArgument.name}<#sep>, </#sep></#list></#if>) / 8.0);-->
+<#--    }-->
 
-    public static int getLengthInBits(PlcValue _value<#if 
type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as 
parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type,
 false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) {
-        int sizeInBits = 0;
-        <#assign defaultCaseOutput=false>
-        <#assign 
dataIoTypeDefinition=type.asDataIoTypeDefinition().orElseThrow()>
-        <#list dataIoTypeDefinition.switchField.orElseThrow().cases as case>
-        <@compress single_line=true>
-        <#if case.discriminatorValueTerms?has_content>
-        if(
-            <#list case.discriminatorValueTerms as discriminatorValueTerm>
-            <#assign 
discriminatorExpression=dataIoTypeDefinition.switchField.orElseThrow().discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow()>
-            <#assign 
discriminatorType=helper.getDiscriminatorTypes()[discriminatorExpression.name]>
-                EvaluationHelper.equals(
-                    
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(), 
discriminatorType, discriminatorExpression, parserArguments)},
-                    <#if discriminatorType.isEnumTypeReference()>
-                    
${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
 discriminatorType, discriminatorValueTerm, parserArguments)}
-                    <#else>
-                    
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(), 
discriminatorType, discriminatorValueTerm, parserArguments)}
-                    </#if>
-                )
-            <#sep> && </#sep>
-            </#list>
-        )
-        <#else>
-            <#assign defaultCaseOutput=true>
-        </#if>
-        </@compress> { // ${case.name}
-            <#list case.fields as field>
-            <#switch field.typeName>
-            <#case "array">
-                <#assign arrayField=field.asArrayField().orElseThrow()>
-                <#assign 
elementTypeReference=arrayField.type.elementTypeReference>
-                PlcList values = (PlcList) _value;
-                <#if case.name == "Struct">
-                // TODO: Finish this!
-                <#elseif elementTypeReference.isComplexTypeReference()>
-                // TODO: Finish this!
-                <#else>
-                sizeInBits += values.getList().size() * 
${elementTypeReference.asSimpleTypeReference().orElseThrow().sizeInBits};
-                </#if>
-                <#break>
-            <#case "const">
-                <#assign constField=field.asConstField().orElseThrow()>
-                // Const Field (${constField.name})
-                <#-- const fields are only simple type -->
-                sizeInBits += 
${constField.type.asSimpleTypeReference().orElseThrow().sizeInBits};
-                <#break>
-            <#case "enum">
-                <#assign enumField=field.asEnumField().orElseThrow()>
-                // Enum field (${enumField.name})
-                sizeInBits += 
${helper.getEnumFieldSimpleTypeReference(enumField.type, 
enumField.fieldName).sizeInBits};
-                <#break>
-            <#case "manual">
-                <#assign manualField=field.asManualField().orElseThrow()>
-                // Manual Field (${manualField.name})
-                sizeInBits += ${helper.toSerializationExpression(manualField, 
helper.intTypeReference, manualField.lengthExpression, 
type.parserArguments.orElse(null))};
-                <#break>
-            <#case "reserved">
-                <#assign reservedField=field.asReservedField().orElseThrow()>
-                // Reserved Field
-                sizeInBits += 
${reservedField.type.asSimpleTypeReference().orElseThrow().sizeInBits};
-                <#break>
-            <#case "simple">
-                <#assign simpleField=field.asSimpleField().orElseThrow()>
-                // Simple Field (${simpleField.name})
-                sizeInBits += 
${simpleField.type.asSimpleTypeReference().orElseThrow().sizeInBits};
-                <#break>
-            </#switch>
-            </#list>
-        }<#sep> else </#sep></#list>
-        return sizeInBits;
-    }
+<#--    public static int getLengthInBits(PlcValue _value<#if 
type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as 
parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type,
 false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) {-->
+<#--        int sizeInBits = 0;-->
+<#--        <#assign defaultCaseOutput=false>-->
+<#--        <#assign 
dataIoTypeDefinition=type.asDataIoTypeDefinition().orElseThrow()>-->
+<#--        <#list dataIoTypeDefinition.switchField.orElseThrow().cases as 
case>-->
+<#--        <@compress single_line=true>-->
+<#--        <#if case.discriminatorValueTerms?has_content>-->
+<#--        if(-->
+<#--            <#list case.discriminatorValueTerms as 
discriminatorValueTerm>-->
+<#--            <#assign 
discriminatorExpression=dataIoTypeDefinition.switchField.orElseThrow().discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow()>-->
+<#--            <#assign 
discriminatorType=helper.getDiscriminatorTypes()[discriminatorExpression.name]>-->
+<#--                EvaluationHelper.equals(-->
+<#--                    
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(), 
discriminatorType, discriminatorExpression, parserArguments)},-->
+<#--                    <#if discriminatorType.isEnumTypeReference()>-->
+<#--                    
${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
 discriminatorType, discriminatorValueTerm, parserArguments)}-->
+<#--                    <#else>-->
+<#--                    
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(), 
discriminatorType, discriminatorValueTerm, parserArguments)}-->
+<#--                    </#if>-->
+<#--                )-->
+<#--            <#sep> && </#sep>-->
+<#--            </#list>-->
+<#--        )-->
+<#--        <#else>-->
+<#--            <#assign defaultCaseOutput=true>-->
+<#--        </#if>-->
+<#--        </@compress> { // ${case.name}-->
+<#--            <#list case.fields as field>-->
+<#--            <#switch field.typeName>-->
+<#--            <#case "array">-->
+<#--                <#assign arrayField=field.asArrayField().orElseThrow()>-->
+<#--                <#assign 
elementTypeReference=arrayField.type.elementTypeReference>-->
+<#--                PlcList values = (PlcList) _value;-->
+<#--                <#if case.name == "Struct">-->
+<#--                // TODO: Finish this!-->
+<#--                <#elseif elementTypeReference.isComplexTypeReference()>-->
+<#--                // TODO: Finish this!-->
+<#--                <#else>-->
+<#--                sizeInBits += values.getList().size() * 
${elementTypeReference.asSimpleTypeReference().orElseThrow().sizeInBits};-->
+<#--                </#if>-->
+<#--                <#break>-->
+<#--            <#case "const">-->
+<#--                <#assign constField=field.asConstField().orElseThrow()>-->
+<#--                // Const Field (${constField.name})-->
+<#--                &lt;#&ndash; const fields are only simple type 
&ndash;&gt;-->
+<#--                sizeInBits += 
${constField.type.asSimpleTypeReference().orElseThrow().sizeInBits};-->
+<#--                <#break>-->
+<#--            <#case "enum">-->
+<#--                <#assign enumField=field.asEnumField().orElseThrow()>-->
+<#--                // Enum field (${enumField.name})-->
+<#--                sizeInBits += 
${helper.getEnumFieldSimpleTypeReference(enumField.type, 
enumField.fieldName).sizeInBits};-->
+<#--                <#break>-->
+<#--            <#case "manual">-->
+<#--                <#assign 
manualField=field.asManualField().orElseThrow()>-->
+<#--                // Manual Field (${manualField.name})-->
+<#--                sizeInBits += 
${helper.toSerializationExpression(manualField, helper.intTypeReference, 
manualField.lengthExpression, type.parserArguments.orElse(null))};-->
+<#--                <#break>-->
+<#--            <#case "reserved">-->
+<#--                <#assign 
reservedField=field.asReservedField().orElseThrow()>-->
+<#--                // Reserved Field-->
+<#--                sizeInBits += 
${reservedField.type.asSimpleTypeReference().orElseThrow().sizeInBits};-->
+<#--                <#break>-->
+<#--            <#case "simple">-->
+<#--                <#assign 
simpleField=field.asSimpleField().orElseThrow()>-->
+<#--                // Simple Field (${simpleField.name})-->
+<#--                sizeInBits += 
${simpleField.type.asSimpleTypeReference().orElseThrow().sizeInBits};-->
+<#--                <#break>-->
+<#--            </#switch>-->
+<#--            </#list>-->
+<#--        }<#sep> else </#sep></#list>-->
+<#--        return sizeInBits;-->
+<#--    }-->
 
-}
+<#--}-->
 </#outputformat>
diff --git 
a/code-generation/language-rust/src/main/resources/templates/rust/enum-template.rs.ftlh
 
b/code-generation/language-rust/src/main/resources/templates/rust/enum-template.rs.ftlh
index 2f58c5914c..ac60e18d2b 100644
--- 
a/code-generation/language-rust/src/main/resources/templates/rust/enum-template.rs.ftlh
+++ 
b/code-generation/language-rust/src/main/resources/templates/rust/enum-template.rs.ftlh
@@ -26,7 +26,8 @@
 <#-- @ftlvariable name="helper" 
type="org.apache.plc4x.language.rust.RustLanguageTemplateHelper" -->
 <#-- @ftlvariable name="tracer" 
type="org.apache.plc4x.plugins.codegenerator.protocol.freemarker.Tracer" -->
 <#-- @ftlvariable name="type" 
type="org.apache.plc4x.plugins.codegenerator.types.definitions.EnumTypeDefinition"
 -->
-${helper.packageName(protocolName, languageName, outputFlavor)?replace(".", 
"/")}/${type.name}.rs
+src/${type.name}.rs
+<#--${helper.packageName(protocolName, languageName, 
outputFlavor)?replace(".", "/")}/${type.name}.rs-->
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -46,9 +47,11 @@ ${helper.packageName(protocolName, languageName, 
outputFlavor)?replace(".", "/")
  * under the License.
  */
 // package ${helper.packageName(protocolName, languageName, outputFlavor)};
-use crate::plc4x_enum;
+<#--use crate::plc4x_enum;-->
 use std::io::{Error, ErrorKind, Read, Write};
-use crate::{Message, NoOption, ReadBuffer, WriteBuffer};
+use plc4rust::{Message, NoOption};
+use plc4rust::read_buffer::ReadBuffer;
+use plc4rust::write_buffer::WriteBuffer;
 
 <#list helper.generateImports(type) as import>
 <#if type.name != import>
@@ -78,7 +81,7 @@ impl 
TryFrom<${helper.getLanguageTypeNameForTypeReference(type.type.orElseThrow(
     fn try_from(value: 
${helper.getLanguageTypeNameForTypeReference(type.type.orElseThrow(), true)}) 
-> Result<Self, Self::Error> {
         match value {
             <#list type.enumValues as enumValue>
-            ${enumValue.value} => ${enumValue.name},
+            ${enumValue.value} => Ok(${type.name}::${enumValue.name}),
             </#list>
             _ => {
                 panic!("Unable to deserialize enum!")
@@ -88,7 +91,7 @@ impl 
TryFrom<${helper.getLanguageTypeNameForTypeReference(type.type.orElseThrow(
 }
 
 impl 
Into<${helper.getLanguageTypeNameForTypeReference(type.type.orElseThrow(), 
true)}> for ${type.name} {
-    fn into(self) -> ${type.name} {
+    fn into(self) -> 
${helper.getLanguageTypeNameForTypeReference(type.type.orElseThrow(), true)} {
         match self {
         <#list type.enumValues as enumValue>
             ${enumValue.name} => ${enumValue.value}<#sep>,</#sep>
diff --git a/plc4rust/src/read_buffer.rs b/plc4rust/src/read_buffer.rs
index 25e1cefbd6..8f4161eb04 100644
--- a/plc4rust/src/read_buffer.rs
+++ b/plc4rust/src/read_buffer.rs
@@ -43,11 +43,11 @@ impl<T: Read> ReadBuffer<T> {
 
 impl<T: Read> ReadBuffer<T> {
 
-    pub(crate) fn read_bit(&mut self) -> Result<bool, std::io::Error> {
+    pub fn read_bit(&mut self) -> Result<bool, std::io::Error> {
         Ok(self.read_u_n(1)? > 0)
     }
 
-    pub(crate) fn read_u8(&mut self) -> Result<u8, std::io::Error> {
+    pub fn read_u8(&mut self) -> Result<u8, std::io::Error> {
         let mut byte = [0_u8; 1];
         self.reader.read(&mut byte)?;
         // println!("read_u8: {}", byte[0]);
@@ -55,7 +55,7 @@ impl<T: Read> ReadBuffer<T> {
         Ok(byte[0])
     }
 
-    pub(crate) fn read_u16(&mut self) -> Result<u16, std::io::Error> {
+    pub fn read_u16(&mut self) -> Result<u16, std::io::Error> {
         let mut bytes = [0_u8; 2];
         self.reader.read(&mut bytes)?;
 
@@ -71,7 +71,11 @@ impl<T: Read> ReadBuffer<T> {
         })
     }
 
-    pub(crate) fn read_u_n(&mut self, number_of_bits: u8) -> Result<u64, 
std::io::Error> {
+    pub fn read_u32(&mut self) -> Result<u32, std::io::Error> {
+        todo!()
+    }
+
+    pub fn read_u_n(&mut self, number_of_bits: u8) -> Result<u64, 
std::io::Error> {
         match self.bit_reader.read(number_of_bits, &mut self.reader) {
             Ok(value) => {
                 Ok(value as u64)

Reply via email to