You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by jf...@apache.org on 2022/06/05 20:30:55 UTC
[plc4x] branch feature/plc4rs updated: Rust Codegeneration generates Cargo file and lib.rs
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 <j....@pragmaticminds.de>
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} {
+<#--<#– 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} {-->
- 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})-->
+<#-- <#– 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.isPr [...]
+<#-- }-->
+<#-- }-->
+<#-- <#– 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, 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()>
+<#-- <#– 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()>-->
- // 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>
+<#-- <#– 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>-->
- <#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>-->
+<#-- <#– 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>-->
- 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})-->
+<#-- <#– 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;-->
+<#-- }-->
-}
+<#--}-->
</#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)