Skip to content

Commit

Permalink
feat(codegen): make the reader and writers a bit more verbose
Browse files Browse the repository at this point in the history
  • Loading branch information
sruehl committed Jan 7, 2022
1 parent 3a4d6de commit d8946d4
Show file tree
Hide file tree
Showing 34 changed files with 172 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,9 @@ public class ${type.name}IO implements MessageInput<${type.name}> {
<#assign namedField = field.asNamedField().orElseThrow()>

<#if manualArrayField.type.isByteBased()>
byte[] ${namedField.name} = readManualByteArrayField("${namedField.name}", readBuffer, () -> (boolean) (${helper.toParseExpression(manualArrayField, helper.boolTypeReference, manualArrayField.loopExpression, parserArguments)}), () -> (${helper.getLanguageTypeNameForField(manualArrayField)}) (${helper.toParseExpression(manualArrayField, manualArrayField.type, manualArrayField.parseExpression, parserArguments)})${helper.getFieldOptions(typedField, parserArguments)});
byte[] ${namedField.name} = readManualByteArrayField("${namedField.name}", readBuffer, (byte[] _values) -> (boolean) (${helper.toParseExpression(manualArrayField, helper.boolTypeReference, manualArrayField.loopExpression, parserArguments)}), () -> (${helper.getLanguageTypeNameForField(manualArrayField)}) (${helper.toParseExpression(manualArrayField, manualArrayField.type, manualArrayField.parseExpression, parserArguments)})${helper.getFieldOptions(typedField, parserArguments)});
<#else>
List<${helper.getNonPrimitiveLanguageTypeNameForField(manualArrayField)}> ${namedField.name} = readManualArrayField("${namedField.name}", readBuffer, () -> (boolean) (${helper.toParseExpression(manualArrayField, helper.boolTypeReference, manualArrayField.loopExpression, parserArguments)}), () -> (${helper.getLanguageTypeNameForField(manualArrayField)}) (${helper.toParseExpression(manualArrayField, manualArrayField.type, manualArrayField.parseExpression, parserArguments)})${helper.getFieldOptions(typedField, parserArguments)});
List<${helper.getNonPrimitiveLanguageTypeNameForField(manualArrayField)}> ${namedField.name} = readManualArrayField("${namedField.name}", readBuffer, (List<${helper.getNonPrimitiveLanguageTypeNameForField(manualArrayField)}> _values) -> (boolean) (${helper.toParseExpression(manualArrayField, helper.boolTypeReference, manualArrayField.loopExpression, parserArguments)}), () -> (${helper.getLanguageTypeNameForField(manualArrayField)}) (${helper.toParseExpression(manualArrayField, manualArrayField.type, manualArrayField.parseExpression, parserArguments)})${helper.getFieldOptions(typedField, parserArguments)});
</#if>
<#break>
<#case "manual">
Expand Down Expand Up @@ -280,7 +280,7 @@ public class ${type.name}IO implements MessageInput<${type.name}> {
<#assign typedField = field.asTypedField().orElseThrow()>
<#assign namedField = field.asNamedField().orElseThrow()>

${helper.getLanguageTypeNameForField(field)} ${namedField.name} = read${field.typeName?cap_first}Field(${helper.getLanguageTypeNameForField(field)}.class, ${helper.toParseExpression(virtualField, virtualField.type, virtualField.valueExpression, parserArguments)}${helper.getFieldOptions(typedField, parserArguments)});
${helper.getLanguageTypeNameForField(field)} ${namedField.name} = read${field.typeName?cap_first}Field("${namedField.name}", ${helper.getLanguageTypeNameForField(field)}.class, ${helper.toParseExpression(virtualField, virtualField.type, virtualField.valueExpression, parserArguments)}${helper.getFieldOptions(typedField, parserArguments)});
<#break>
<#case "validation">
<#assign validationField = field.asValidationField().orElseThrow()>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,17 @@

import org.apache.plc4x.java.spi.codegen.FieldCommons;
import org.apache.plc4x.java.spi.codegen.io.DataReader;
import org.apache.plc4x.java.spi.generation.ParseException;
import org.apache.plc4x.java.spi.generation.WithReaderArgs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* This reader should actually never be used as an abstract field never gets read, it only makes sure
* abstract accessor methods are generated in the abstract parent type.
*
* @param <T>
*/
public class FieldReaderAbstract<T> implements FieldCommons {

private static final Logger LOGGER = LoggerFactory.getLogger(FieldReaderAbstract.class);

public T readAbstractField(String logicalName, DataReader<T> dataReader, WithReaderArgs... readerArgs) throws ParseException {
public T readAbstractField(String ignored1, DataReader<T> ignored2, WithReaderArgs... ignored3) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,24 @@
package org.apache.plc4x.java.spi.codegen.fields;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.NotImplementedException;
import org.apache.plc4x.java.spi.codegen.FieldCommons;
import org.apache.plc4x.java.spi.codegen.io.DataReader;
import org.apache.plc4x.java.spi.generation.ParseException;
import org.apache.plc4x.java.spi.generation.WithReaderArgs;
import org.apache.plc4x.java.spi.generation.WithReaderWriterArgs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;

public class FieldReaderArray<T> implements FieldCommons {

private static final Logger LOGGER = LoggerFactory.getLogger(FieldReaderArray.class);

public List<T> readFieldCount(String logicalName, DataReader<T> dataReader, long count, WithReaderArgs... readerArgs) throws ParseException {
LOGGER.debug("reading field {}. Count: {}", logicalName, count);
if (count > Integer.MAX_VALUE) {
throw new ParseException("Array count of " + count + " exceeds the maximum allowed count of " + Integer.MAX_VALUE);
}
Expand All @@ -45,23 +49,33 @@ public List<T> readFieldCount(String logicalName, DataReader<T> dataReader, long
result.add(dataReader.read("", readerArgs));
}
dataReader.closeContext(logicalName, readerArgs);
LOGGER.debug("done reading field {}", logicalName);
return result;
}

public List<T> readFieldLength(String logicalName, DataReader<T> dataReader, int length, WithReaderArgs... readerArgs) throws ParseException {
LOGGER.debug("reading field {}. Length: {}", logicalName, length);
// Ensure we have the render as list argument present
readerArgs = ArrayUtils.add(readerArgs, WithReaderWriterArgs.WithRenderAsList(true));
dataReader.pullContext(logicalName, readerArgs);
int startPos = dataReader.getPos();
List<T> result = new ArrayList<>();
while (dataReader.getPos() < startPos + length) {
result.add(dataReader.read("", readerArgs));
int numberOfElements = 0;
int stopPosition = startPos + length;
LOGGER.debug("start reading at pos {} while < {}", startPos, stopPosition);
while (dataReader.getPos() < stopPosition) {
numberOfElements++;
T element = dataReader.read("", readerArgs);
LOGGER.debug("Read element[{}] {}", numberOfElements, element);
result.add(element);
}
dataReader.closeContext(logicalName, readerArgs);
LOGGER.debug("done reading field {}", logicalName);
return result;
}

public List<T> readFieldTerminated(String logicalName, DataReader<T> dataReader, Supplier<Boolean> termination, WithReaderArgs... readerArgs) throws ParseException {
LOGGER.debug("reading field {}", logicalName);
// Ensure we have the render as list argument present
readerArgs = ArrayUtils.add(readerArgs, WithReaderWriterArgs.WithRenderAsList(true));
dataReader.pullContext(logicalName, readerArgs);
Expand All @@ -70,6 +84,7 @@ public List<T> readFieldTerminated(String logicalName, DataReader<T> dataReader,
result.add(dataReader.read("", readerArgs));
}
dataReader.closeContext(logicalName, readerArgs);
LOGGER.debug("done reading field {}", logicalName);
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,18 @@

public class FieldReaderAssert<T> implements FieldCommons {

private static final Logger LOGGER = LoggerFactory.getLogger(FieldReaderAssert.class);

public T readAssertField(String logicalName, DataReader<T> dataReader, T expectedValue, WithReaderArgs... readerArgs) throws ParseException {
LOGGER.debug("reading field {}", logicalName);
T assertValue;
try {
assertValue = dataReader.read(logicalName, readerArgs);
} catch (ArrayIndexOutOfBoundsException e) {
throw new ParseAssertException("Not enough data", e);
throw new ParseAssertException("Field: " + logicalName + ": Not enough data", e);
}
if (!Objects.equals(assertValue, expectedValue)) {
throw new ParseAssertException("Actual value " + assertValue + " doesn't match expected " + expectedValue);
throw new ParseAssertException("Field: " + logicalName + ": Actual value " + assertValue + " doesn't match expected " + expectedValue);
}
return assertValue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@

public class FieldReaderChecksum<T> implements FieldCommons {

private static final Logger LOGGER = LoggerFactory.getLogger(FieldReaderChecksum.class);

public T readChecksumField(String logicalName, DataReader<T> dataReader, T referenceValue, WithReaderArgs... readerArgs) throws ParseException {
LOGGER.debug("reading field {}", logicalName);
T checksumValue = switchParseByteOrderIfNecessary(() -> dataReader.read(logicalName, readerArgs), dataReader, extractByteOder(readerArgs).orElse(null));
if (!Objects.equals(checksumValue, referenceValue)) {
throw new ParseException("Checksum value '" + checksumValue + "' doesn't match expected '" + referenceValue + "'");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@

public class FieldReaderConst<T> implements FieldCommons {

private static final Logger LOGGER = LoggerFactory.getLogger(FieldReaderConst.class);

public T readConstField(String logicalName, DataReader<T> dataReader, T expectedValue, WithReaderArgs... readerArgs) throws ParseException {
LOGGER.debug("reading field {}", logicalName);
T constValue = switchParseByteOrderIfNecessary(() -> dataReader.read(logicalName, readerArgs), dataReader, extractByteOder(readerArgs).orElse(null));
if (!Objects.equals(constValue, expectedValue)) {
throw new ParseException("Actual value " + constValue + " doesn't match expected " + expectedValue + ". Byte position: " + dataReader.getPos());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@

public class FieldReaderDiscriminator<T> implements FieldCommons {

private static final Logger LOGGER = LoggerFactory.getLogger(FieldReaderDiscriminator.class);

public T readDiscriminatorField(String logicalName, DataReader<T> dataReader, WithReaderArgs... readerArgs) throws ParseException {
LOGGER.debug("reading field {}", logicalName);
return switchParseByteOrderIfNecessary(() -> dataReader.read(logicalName, readerArgs), dataReader, extractByteOder(readerArgs).orElse(null));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
*/
package org.apache.plc4x.java.spi.codegen.fields;

import org.apache.commons.lang3.NotImplementedException;
import org.apache.plc4x.java.spi.codegen.FieldCommons;
import org.apache.plc4x.java.spi.codegen.io.DataReader;
import org.apache.plc4x.java.spi.generation.ParseException;
Expand All @@ -29,7 +28,10 @@

public class FieldReaderEnum<T> implements FieldCommons {

private static final Logger LOGGER = LoggerFactory.getLogger(FieldReaderEnum.class);

public T readEnumField(String logicalName, String innerName, DataReader<T> dataReader, WithReaderArgs... readerArgs) throws ParseException {
LOGGER.debug("reading field {}", logicalName);
dataReader.pullContext(logicalName, WithReaderWriterArgs.WithRenderAsList(true));
T result = switchParseByteOrderIfNecessary(() -> dataReader.read(innerName, readerArgs), dataReader, extractByteOder(readerArgs).orElse(null));
dataReader.closeContext(logicalName, WithReaderWriterArgs.WithRenderAsList(true));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@
import org.apache.plc4x.java.spi.generation.WithReaderArgs;

import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;

public class FieldReaderFactory {

@SuppressWarnings("unused")
public static <T> T readAbstractField(String logicalName, DataReader<T> dataReader, WithReaderArgs... readerArgs) throws ParseException {
return new FieldReaderAbstract<T>().readAbstractField(logicalName, dataReader, readerArgs);
}
Expand Down Expand Up @@ -93,11 +95,11 @@ public static <T> T readOptionalField(String logicalName, DataReader<T> dataRead
return new FieldReaderOptional<T>().readOptionalField(logicalName, dataReader, condition, readerArgs);
}

public static byte[] readManualByteArrayField(String logicalName, ReadBuffer readBuffer, Supplier<Boolean> termination, ParseSupplier<Byte> parse, WithReaderArgs... readerArgs) throws ParseException {
public static byte[] readManualByteArrayField(String logicalName, ReadBuffer readBuffer, Function<byte[], Boolean> termination, ParseSupplier<Byte> parse, WithReaderArgs... readerArgs) throws ParseException {
return new FieldReaderManualArray<Byte>().readManualByteArrayField(logicalName, readBuffer, termination, parse, readerArgs);
}

public static <T> List<T> readManualArrayField(String logicalName, ReadBuffer readBuffer, Supplier<Boolean> termination, ParseSupplier<T> parse, WithReaderArgs... readerArgs) throws ParseException {
public static <T> List<T> readManualArrayField(String logicalName, ReadBuffer readBuffer, Function<List<T>, Boolean> termination, ParseSupplier<T> parse, WithReaderArgs... readerArgs) throws ParseException {
return new FieldReaderManualArray<T>().readManualArrayField(logicalName, readBuffer, termination, parse, readerArgs);
}

Expand All @@ -121,8 +123,8 @@ public static <T> T readUnknownField(String logicalName, DataReader<T> dataReade
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);
public static <T> T readVirtualField(String logicalName, Class<T> type, Object valueExpression, WithReaderArgs... readerArgs) throws ParseException {
return new FieldReaderVirtual<T>().readVirtualField(logicalName, type, valueExpression, readerArgs);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@

public class FieldReaderImplicit<T> implements FieldCommons {

private static final Logger LOGGER = LoggerFactory.getLogger(FieldReaderImplicit.class);

public T readImplicitField(String logicalName, DataReader<T> dataReader, WithReaderArgs... readerArgs) throws ParseException {
LOGGER.debug("reading field {}", logicalName);
return switchParseByteOrderIfNecessary(() -> dataReader.read(logicalName, readerArgs), dataReader, extractByteOder(readerArgs).orElse(null));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@

public class FieldReaderManual<T> implements FieldCommons {

private static final Logger LOGGER = LoggerFactory.getLogger(FieldReaderManual.class);

public T readManualField(String logicalName, ReadBuffer readBuffer, ParseSupplier<T> parseFunction, WithReaderArgs... readerArgs) throws ParseException {
LOGGER.debug("reading field {}", logicalName);
readBuffer.pullContext(logicalName);
T value = switchParseByteOrderIfNecessary(parseFunction::get, readBuffer, extractByteOder(readerArgs).orElse(null));
readBuffer.closeContext(logicalName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,32 +31,46 @@
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;

public class FieldReaderManualArray<T> implements FieldCommons {

public byte[] readManualByteArrayField(String logicalName, ReadBuffer readBuffer, Supplier<Boolean> termination, ParseSupplier<T> parse, WithReaderArgs... readerArgs) throws ParseException {
private static final Logger LOGGER = LoggerFactory.getLogger(FieldReaderManualArray.class);

public byte[] readManualByteArrayField(String logicalName, ReadBuffer readBuffer, Function<byte[],Boolean> termination, ParseSupplier<T> parse, WithReaderArgs... readerArgs) throws ParseException {
LOGGER.debug("reading field {}", logicalName);
// Ensure we have the render as list argument present
readerArgs = ArrayUtils.add(readerArgs, WithReaderWriterArgs.WithRenderAsList(true));
readBuffer.pullContext(logicalName, readerArgs);
List<Byte> result = new ArrayList<>();
while (!termination.get()) {
result.add((Byte) parse.get());
while (!termination.apply(ArrayUtils.toPrimitive(result.toArray(new Byte[0])))) {
//TODO: maybe switch to iterator here
Byte element = (Byte) parse.get();
LOGGER.debug("Adding element {}", element);
result.add(element);
}
readBuffer.closeContext(logicalName, readerArgs);
LOGGER.debug("done reading field {}", logicalName);
return ArrayUtils.toPrimitive(result.toArray(new Byte[0]));
}

public List<T> readManualArrayField(String logicalName, ReadBuffer readBuffer, Supplier<Boolean> termination, ParseSupplier<T> parse, WithReaderArgs... readerArgs) throws ParseException {
public List<T> readManualArrayField(String logicalName, ReadBuffer readBuffer, Function<List<T>,Boolean> termination, ParseSupplier<T> parse, WithReaderArgs... readerArgs) throws ParseException {
LOGGER.debug("reading field {}", logicalName);
// Ensure we have the render as list argument present
readerArgs = ArrayUtils.add(readerArgs, WithReaderWriterArgs.WithRenderAsList(true));
readBuffer.pullContext(logicalName, readerArgs);
List<T> result = new ArrayList<>();
while (!termination.get()) {
result.add(parse.get());
while (!termination.apply(Collections.unmodifiableList(result))) {
//TODO: maybe switch to iterator here
T element = parse.get();
LOGGER.debug("Adding element {}", element);
result.add(element);
}
readBuffer.closeContext(logicalName, readerArgs);
LOGGER.debug("done reading field {}", logicalName);
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,19 @@ public class FieldReaderOptional<T> implements FieldCommons {
private static final Logger LOGGER = LoggerFactory.getLogger(FieldReaderOptional.class);

public T readOptionalField(String logicalName, DataReader<T> dataReader, boolean condition, WithReaderArgs... readerArgs) throws ParseException {
LOGGER.debug("reading field {}", logicalName);
if (!condition) {
LOGGER.debug("Condition doesnt match for field {}", logicalName);
LOGGER.debug("Condition doesn't match for field {}", logicalName);
return null;
}

int curPos = dataReader.getPos();
try {
return switchParseByteOrderIfNecessary(() -> dataReader.read(logicalName, readerArgs), dataReader, extractByteOder(readerArgs).orElse(null));
T field = switchParseByteOrderIfNecessary(() -> dataReader.read(logicalName, readerArgs), dataReader, extractByteOder(readerArgs).orElse(null));
LOGGER.debug("done reading field {}.{}", logicalName, field);
return field;
} catch (ParseAssertException e) {
LOGGER.debug("Assertion doesnt match for field {}", logicalName, e);
LOGGER.debug("Assertion doesn't match for field {}. Resetting read position to {}", logicalName, curPos, e);
dataReader.setPos(curPos);
return null;
}
Expand Down
Loading

0 comments on commit d8946d4

Please sign in to comment.