You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2021/10/20 19:49:38 UTC
[plc4x] branch feature/mspec-ng updated: - Continued implementing
optional, virtual, ... fields.
This is an automated email from the ASF dual-hosted git repository.
cdutz pushed a commit to branch feature/mspec-ng
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/feature/mspec-ng by this push:
new e4d93c4 - Continued implementing optional, virtual, ... fields.
e4d93c4 is described below
commit e4d93c45aeb6996b7faf35f13c01f16f3a1e4b52
Author: cdutz <ch...@c-ware.de>
AuthorDate: Wed Oct 20 21:49:28 2021 +0200
- Continued implementing optional, virtual, ... fields.
---
.../language/java/JavaLanguageTemplateHelper.java | 17 ++++-
.../resources/templates/java/io-template.java.ftlh | 76 +++-------------------
.../spi/codegen/fields/FieldReaderFactory.java | 8 +++
.../spi/codegen/fields/FieldReaderVirtual.java | 9 ++-
...ReaderComplex.java => ComplexTypeSupplier.java} | 7 +-
.../java/spi/codegen/io/DataReaderComplex.java | 2 +-
.../spi/codegen/io/DataReaderComplexDefault.java | 7 +-
.../java/spi/codegen/io/DataReaderEnumDefault.java | 4 +-
.../java/spi/generation/WithReaderWriterArgs.java | 2 +
.../s7/src/main/resources/protocols/s7/s7.mspec | 40 ++++++------
10 files changed, 72 insertions(+), 100 deletions(-)
diff --git a/code-generation/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java b/code-generation/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
index 1a205ec..2eafd94 100644
--- a/code-generation/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
+++ b/code-generation/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
@@ -374,7 +374,22 @@ public class JavaLanguageTemplateHelper extends BaseFreemarkerLanguageTemplateHe
SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
return getDataReaderCall(simpleTypeReference);
} else if (typeReference.isComplexTypeReference()) {
- return "new DataReaderComplex(readBuffer)";
+ final ComplexTypeReference complexTypeReference = typeReference.asComplexTypeReference().get();
+ String parserArguments = "";
+ if(complexTypeReference.getParams().isPresent()) {
+ final List<Term> terms = complexTypeReference.getParams().get();
+ StringBuilder sb = new StringBuilder();
+ for (Term term : terms) {
+ sb.append(", ").append(toParseExpression(null, term, null));
+ }
+ parserArguments = sb.toString();
+ }
+ return "new DataReaderComplexDefault<>(new ComplexTypeSupplier<" + getLanguageTypeNameForTypeReference(typeReference) + ">() {" +
+ " @Override\n" +
+ " public " + getLanguageTypeNameForTypeReference(typeReference) + " get() throws ParseException {\n" +
+ " return " + getLanguageTypeNameForTypeReference(typeReference) + "IO.staticParse(readBuffer" + parserArguments + ");\n" +
+ " }" +
+ "}, readBuffer)";
} else {
throw new IllegalStateException("What is this type? " + typeReference);
}
diff --git a/code-generation/language-java/src/main/resources/templates/java/io-template.java.ftlh b/code-generation/language-java/src/main/resources/templates/java/io-template.java.ftlh
index 7167fec..2232d00 100644
--- a/code-generation/language-java/src/main/resources/templates/java/io-template.java.ftlh
+++ b/code-generation/language-java/src/main/resources/templates/java/io-template.java.ftlh
@@ -444,71 +444,16 @@ public class ${type.name}IO implements <#if outputFlavor != "passive">MessageIO<
// Manual Field (${manualField.name})
${helper.getLanguageTypeNameForField(field)} ${manualField.name} = (${helper.getLanguageTypeNameForField(field)}) (${helper.toParseExpression(manualField, manualField.parseExpression, parserArguments)});
<#break>
- <#-- TODO: Port this -->
<#case "optional">
<#assign optionalField = field.asOptionalField().orElseThrow()>
+ <#assign typedField = field.asTypedField().orElseThrow()>
+ <#assign namedField = field.asNamedField().orElseThrow()>
- // Optional Field (${optionalField.name}) (Can be skipped, if a given expression evaluates to false)
- ${helper.getLanguageTypeNameForField(optionalField)} ${optionalField.name} = null;
- <#-- TODO: we need to initalize base types-->
- curPos = readBuffer.getPos();
- try {
+ // ${field.typeName?cap_first} Field (${namedField.name}) (Can be skipped, if a given expression evaluates to false)
<#if optionalField.conditionExpression.present && optionalField.conditionExpression.orElseThrow().contains("curPos")>
- curPos = readBuffer.getPos();
- </#if>
- <#if optionalField.conditionExpression.present>
- if(${helper.toParseExpression(optionalField, optionalField.conditionExpression.get(), parserArguments)}) {
+ curPos = readBuffer.getPos();
</#if>
- <@compress single_line=true>
- ${optionalField.name} =
- <#if helper.isEnumField(optionalField)>
- ${helper.getLanguageTypeNameForField(optionalField)}.enumForValue(
- ${helper.getReadBufferReadMethodCall(optionalField.name, helper.getEnumBaseTypeReference(optionalField.type), "", optionalField)}
- )
- <#elseif helper.isComplexTypeReference(optionalField.type)>
- <#assign complexTypeReference=optionalField.type.asComplexTypeReference().orElseThrow()>
- <#assign typeName=complexTypeReference.name>
- <#assign typeDefinition=helper.getTypeDefinitionForTypeReference(complexTypeReference)>
- <#if typeDefinition.isDiscriminatedChildTypeDefinition()>
- <#-- Usually you don't use child directly unless they are parameterized #-->
- <#assign typeName=typeDefinition.parentType.name>
- <#assign typeDefinition=typeDefinition.parentType>
- </#if>
- <#-- We downcast to the referenced type-->
- (${complexTypeReference.name}) ${typeName}IO.staticParse(
- readBuffer
- <#if field.params.isPresent()>,
- <#list field.params.orElseThrow() as parserArgument>
- (${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(optionalField.type, parserArgument?index), true)})
- (${helper.toParseExpression(optionalField, parserArgument, parserArguments)})<#sep>, </#sep>
- </#list>
- </#if>
- <#if complexTypeReference.params.isPresent() && typeDefinition.parserArguments.isPresent()>
- <#assign argumentOffset=0>
- <#if field.params.isPresent()><#assign argumentOffset=field.params.orElseThrow()?size></#if>
- ,
- <#list complexTypeReference.params.orElseThrow() as typeParam>
- <#-- We cast here explicitly as java sometimes can't infer the type. e.g. 0 is a int and not a byte#-->
- (${helper.getLanguageTypeNameForTypeReference(typeDefinition.parserArguments.orElseThrow()[typeParam?index + argumentOffset].type, true)})
- ${helper.toAccessExpression(null, typeParam, null)}<#sep>, </#sep>
- </#list>
- </#if>
- )
- <#else>
- ${helper.getReadBufferReadMethodCall(optionalField.name, optionalField.type.asSimpleTypeReference().orElseThrow(), "", optionalField)}
- </#if>
- ;
- </...@compress>
-
- <#if optionalField.conditionExpression.present>
- }
- </#if>
- if (1 == 2) {
- throw new ParseAssertException("oh no java");
- }
- } catch(ParseAssertException ignore){
- readBuffer.reset(curPos);
- }
+ ${helper.getLanguageTypeNameForField(field)} ${namedField.name} = read${field.typeName?cap_first}Field("${namedField.name}", ${helper.getDataReaderCall(typedField.type)}, <#if optionalField.conditionExpression.present>${helper.toParseExpression(optionalField, optionalField.conditionExpression.get(), parserArguments)}<#else>true</#if>);
<#break>
<#case "assert">
<#assign assertField = field.asAssertField().orElseThrow()>
@@ -647,16 +592,13 @@ public class ${type.name}IO implements <#if outputFlavor != "passive">MessageIO<
// ${field.typeName?cap_first} Field
read${field.typeName?cap_first}Field("unknown", ${helper.getDataReaderCall(typedField.type)});
<#break>
- <#-- TODO: Port this -->
<#case "virtual">
<#assign virtualField = field.asVirtualField().orElseThrow()>
+ <#assign typedField = field.asTypedField().orElseThrow()>
+ <#assign namedField = field.asNamedField().orElseThrow()>
- // Virtual field (Just declare a local variable so we can access it in the parser)
- <#if helper.getLanguageTypeNameForField(field) = 'String'>
- ${helper.getLanguageTypeNameForField(field)} ${virtualField.name} = ${helper.getLanguageTypeNameForField(field)}.valueOf(${helper.toParseExpression(virtualField, virtualField.valueExpression, parserArguments)});
- <#else>
- ${helper.getLanguageTypeNameForField(field)} ${virtualField.name} = (${helper.getLanguageTypeNameForField(field)}) (${helper.toParseExpression(virtualField, virtualField.valueExpression, parserArguments)});
- </#if>
+ // ${field.typeName?cap_first} Field (${namedField.name})
+ ${helper.getLanguageTypeNameForField(field)} ${namedField.name} = read${field.typeName?cap_first}Field(${helper.getLanguageTypeNameForField(field)}.class, ${helper.toParseExpression(virtualField, virtualField.valueExpression, parserArguments)});
<#break>
</#switch>
</#list>
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/fields/FieldReaderFactory.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/fields/FieldReaderFactory.java
index f81a75d..9dc32dc 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/fields/FieldReaderFactory.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/fields/FieldReaderFactory.java
@@ -52,6 +52,10 @@ public class FieldReaderFactory {
return new FieldReaderImplicit<T>().readField(logicalName, dataReader, readerArgs);
}
+ public static <T> T readOptionalField(String logicalName, DataReader<T> dataReader, boolean condition, WithReaderArgs... readerArgs) throws ParseException {
+ return new FieldReaderOptional<T>().readOptionalField(logicalName, dataReader, condition, readerArgs);
+ }
+
public static <T> void readPaddingField(DataReader<T> dataReader, int timesPadding, WithReaderArgs... readerArgs) throws ParseException {
new FieldReaderPadding<T>().readPaddingField(dataReader, timesPadding, readerArgs);
}
@@ -64,4 +68,8 @@ public class FieldReaderFactory {
return new FieldReaderUnknown<T>().readUnknownField(logicalName, dataReader, readerArgs);
}
+ public static <T> T readVirtualField(Class<T> type, Object valueExpression, WithReaderArgs... readerArgs) throws ParseException {
+ return new FieldReaderVirtual<T>().readVirtualField(type, valueExpression, readerArgs);
+ }
+
}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/fields/FieldReaderVirtual.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/fields/FieldReaderVirtual.java
index 61a8b21..375c515 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/fields/FieldReaderVirtual.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/fields/FieldReaderVirtual.java
@@ -30,7 +30,14 @@ public class FieldReaderVirtual<T> implements FieldReader<T> {
@Override
public T readField(String logicalName, DataReader<T> dataReader, WithReaderArgs... readerArgs) throws ParseException {
- return switchByteOrderIfNecessary(() -> dataReader.read(logicalName, readerArgs), dataReader, extractByteOder(readerArgs).orElse(null));
+ throw new IllegalStateException("not possible with unknown field");
+ }
+
+ public T readVirtualField(Class<T> type, Object valueExpression, WithReaderArgs... readerArgs) throws ParseException {
+ if(type == String.class) {
+ return (T) String.valueOf(valueExpression);
+ }
+ return (T) valueExpression;
}
}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/io/DataReaderComplex.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/io/ComplexTypeSupplier.java
similarity index 77%
copy from plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/io/DataReaderComplex.java
copy to plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/io/ComplexTypeSupplier.java
index 662ef53..2ad9d4d 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/io/DataReaderComplex.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/io/ComplexTypeSupplier.java
@@ -19,12 +19,9 @@
package org.apache.plc4x.java.spi.codegen.io;
import org.apache.plc4x.java.spi.generation.ParseException;
-import org.apache.plc4x.java.spi.generation.WithReaderArgs;
-import java.util.function.Supplier;
+public interface ComplexTypeSupplier<T> {
-public interface DataReaderComplex<T> extends DataReader<T> {
-
- T read(String logicalName, Supplier<T> complexSupplier, WithReaderArgs... readerArgs) throws ParseException;
+ T get() throws ParseException;
}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/io/DataReaderComplex.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/io/DataReaderComplex.java
index 662ef53..41b18d2 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/io/DataReaderComplex.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/io/DataReaderComplex.java
@@ -25,6 +25,6 @@ import java.util.function.Supplier;
public interface DataReaderComplex<T> extends DataReader<T> {
- T read(String logicalName, Supplier<T> complexSupplier, WithReaderArgs... readerArgs) throws ParseException;
+ T read(String logicalName, ComplexTypeSupplier<T> complexSupplier, WithReaderArgs... readerArgs) throws ParseException;
}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/io/DataReaderComplexDefault.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/io/DataReaderComplexDefault.java
index 91944f7..ee60319 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/io/DataReaderComplexDefault.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/io/DataReaderComplexDefault.java
@@ -26,12 +26,13 @@ import org.apache.plc4x.java.spi.generation.WithReaderArgs;
import java.util.function.Supplier;
public class DataReaderComplexDefault<T> implements DataReaderComplex<T> {
- private final Supplier<T> complexSupplier;
+
+ private final ComplexTypeSupplier<T> complexSupplier;
// TODO: maybe replace with resetable or something so its clear that that's the only purpose
private final ReadBuffer readBuffer;
- public DataReaderComplexDefault(Supplier<T> complexSupplier, ReadBuffer readBuffer) {
+ public DataReaderComplexDefault(ComplexTypeSupplier<T> complexSupplier, ReadBuffer readBuffer) {
this.complexSupplier = complexSupplier;
this.readBuffer = readBuffer;
}
@@ -61,7 +62,7 @@ public class DataReaderComplexDefault<T> implements DataReaderComplex<T> {
return read(logicalName, complexSupplier, readerArgs);
}
- public T read(String logicalName, Supplier<T> complexSupplier, WithReaderArgs... readerArgs) throws ParseException {
+ public T read(String logicalName, ComplexTypeSupplier<T> complexSupplier, WithReaderArgs... readerArgs) throws ParseException {
readBuffer.pullContext(logicalName,readerArgs);
final T t = complexSupplier.get();
readBuffer.closeContext(logicalName,readerArgs);
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/io/DataReaderEnumDefault.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/io/DataReaderEnumDefault.java
index fc7b398..e3f758e 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/io/DataReaderEnumDefault.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/codegen/io/DataReaderEnumDefault.java
@@ -27,9 +27,9 @@ import java.util.function.Function;
public class DataReaderEnumDefault<T, I> implements DataReaderEnum<T> {
private final Function<I, T> enumResolver;
- private final DataReaderSimple<I> dataReader;
+ private final DataReader<I> dataReader;
- public DataReaderEnumDefault(Function<I, T> enumResolver, DataReaderSimple<I> dataReader) {
+ public DataReaderEnumDefault(Function<I, T> enumResolver, DataReader<I> dataReader) {
this.enumResolver = enumResolver;
this.dataReader = dataReader;
}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WithReaderWriterArgs.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WithReaderWriterArgs.java
index 9baaed2..05a25dd 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WithReaderWriterArgs.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WithReaderWriterArgs.java
@@ -19,6 +19,7 @@
package org.apache.plc4x.java.spi.generation;
public interface WithReaderWriterArgs extends WithReaderArgs, WithWriterArgs {
+
static WithReaderWriterArgs WithRenderAsList(boolean renderAsList) {
return (withRenderAsList) () -> renderAsList;
}
@@ -26,6 +27,7 @@ public interface WithReaderWriterArgs extends WithReaderArgs, WithWriterArgs {
static WithReaderWriterArgs WithAdditionalStringRepresentation(String stringRepresentation) {
return (withAdditionalStringRepresentation) () -> stringRepresentation;
}
+
}
interface withRenderAsList extends WithReaderWriterArgs {
diff --git a/protocols/s7/src/main/resources/protocols/s7/s7.mspec b/protocols/s7/src/main/resources/protocols/s7/s7.mspec
index 9e35fa6..4249c7b 100644
--- a/protocols/s7/src/main/resources/protocols/s7/s7.mspec
+++ b/protocols/s7/src/main/resources/protocols/s7/s7.mspec
@@ -22,10 +22,10 @@
////////////////////////////////////////////////////////////////
[type 'TPKTPacket' byteOrder='"BIG_ENDIAN"'
- [const uint 8 'protocolId' '0x03']
- [reserved uint 8 '0x00']
- [implicit uint 16 'len' 'payload.lengthInBytes + 4']
- [simple COTPPacket 'payload' ['len - 4']]
+ [const uint 8 'protocolId' '0x03' ]
+ [reserved uint 8 '0x00' ]
+ [implicit uint 16 'len' 'payload.lengthInBytes + 4']
+ [simple COTPPacket ['len - 4'] 'payload' ]
]
////////////////////////////////////////////////////////////////
@@ -37,35 +37,35 @@
[discriminator uint 8 'tpduCode']
[typeSwitch 'tpduCode'
['0xF0' COTPPacketData
- [simple bit 'eot']
- [simple uint 7 'tpduRef']
+ [simple bit 'eot' ]
+ [simple uint 7 'tpduRef' ]
]
['0xE0' COTPPacketConnectionRequest
[simple uint 16 'destinationReference']
- [simple uint 16 'sourceReference']
- [simple COTPProtocolClass 'protocolClass']
+ [simple uint 16 'sourceReference' ]
+ [simple COTPProtocolClass 'protocolClass' ]
]
['0xD0' COTPPacketConnectionResponse
[simple uint 16 'destinationReference']
- [simple uint 16 'sourceReference']
- [simple COTPProtocolClass 'protocolClass']
+ [simple uint 16 'sourceReference' ]
+ [simple COTPProtocolClass 'protocolClass' ]
]
['0x80' COTPPacketDisconnectRequest
[simple uint 16 'destinationReference']
- [simple uint 16 'sourceReference']
- [simple COTPProtocolClass 'protocolClass']
+ [simple uint 16 'sourceReference' ]
+ [simple COTPProtocolClass 'protocolClass' ]
]
['0xC0' COTPPacketDisconnectResponse
- [simple uint 16 'destinationReference']
- [simple uint 16 'sourceReference']
+ [simple uint 16 'destinationReference' ]
+ [simple uint 16 'sourceReference' ]
]
['0x70' COTPPacketTpduError
- [simple uint 16 'destinationReference']
- [simple uint 8 'rejectCause']
+ [simple uint 16 'destinationReference' ]
+ [simple uint 8 'rejectCause' ]
]
]
- [array COTPParameter 'parameters' length '(headerLength + 1) - curPos' ['(headerLength + 1) - curPos']]
- [optional S7Message 'payload' 'curPos < cotpLen']
+ [array COTPParameter ['(headerLength + 1) - curPos'] 'parameters' length '(headerLength + 1) - curPos']
+ [optional S7Message 'payload' 'curPos < cotpLen']
]
[discriminatedType 'COTPParameter' [uint 8 'rest']
@@ -115,8 +115,8 @@
['0x07' S7MessageUserData
]
]
- [optional S7Parameter 'parameter' 'parameterLength > 0' ['messageType']]
- [optional S7Payload 'payload' 'payloadLength > 0' ['messageType', 'parameter']]
+ [optional S7Parameter ['messageType'] 'parameter' 'parameterLength > 0']
+ [optional S7Payload ['messageType', 'parameter'] 'payload' 'payloadLength > 0' ]
]
////////////////////////////////////////////////////////////////