You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by sr...@apache.org on 2026/08/19 18:04:22 UTC
(plc4x) 03/12: fix(codegen/go): pass the field encoding through the deprecated data-io path
This is an automated email from the ASF dual-hosted git repository.
sruehl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit b40e3ac731ca36a5e451d62666496b5d6306c389
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Wed Aug 19 18:05:16 2026 +0200
fix(codegen/go): pass the field encoding through the deprecated data-io path
The migrated read and write templates forward an mspec `encoding` to the
buffers, but the deprecated data-io path dropped it silently. Now that the Go
buffers act on BCD that asymmetry has teeth: the S7 DATE_AND_TIME data item
would serialize its manual `year` field as BCD, because serializeSiemensYear
passes the option itself, while month, day, hour and the rest went out as raw
binary - half a frame in each encoding.
This only takes effect once the Go models are regenerated; the checked-in
generated code still carries the old call shape. The read half of that
particular data item is dead either way - it assigns every field to `_` and
falls through to "unsupported type" - so nothing regresses in the meantime.
---
.../language/go/GoLanguageTemplateHelper.java | 69 +++++++++++++++-------
1 file changed, 49 insertions(+), 20 deletions(-)
diff --git a/code-generation/language/go/src/main/java/org/apache/plc4x/language/go/GoLanguageTemplateHelper.java b/code-generation/language/go/src/main/java/org/apache/plc4x/language/go/GoLanguageTemplateHelper.java
index b4e8ad2075..b05e25e3b1 100644
--- a/code-generation/language/go/src/main/java/org/apache/plc4x/language/go/GoLanguageTemplateHelper.java
+++ b/code-generation/language/go/src/main/java/org/apache/plc4x/language/go/GoLanguageTemplateHelper.java
@@ -381,6 +381,35 @@ public class GoLanguageTemplateHelper extends BaseFreemarkerLanguageTemplateHelp
return isNotAnComplexTypeReference && arrayTypeIsNotAnComplexTypeReference;
}
+ /**
+ * Renders the trailing {@code , utils.WithEncoding("...")} argument for a numeric field that
+ * declares an {@code encoding} in the mspec, or the empty string when it declares none.
+ * <p>
+ * The migrated (non deprecated) read/write templates pass the encoding through as
+ * {@code codegen.WithEncoding(...)}, but the deprecated data-io path below used to drop it
+ * silently. That made the S7 {@code DATE_AND_TIME} data item emit a half BCD, half raw binary
+ * frame once the Go byte buffers started honouring {@code encoding='"BCD"'}: the manual
+ * {@code year} field went through {@code serializeSiemensYear} (which passes the option
+ * explicitly) while {@code month}/{@code day}/... did not.
+ *
+ * @param field the field being rendered, may be {@code null}
+ * @return the writer/reader argument to append, or {@code ""}
+ */
+ private String getEncodingOption(TypedField field) {
+ if (field == null) {
+ return "";
+ }
+ final Optional<Term> encodingTerm = field.getEncoding();
+ if (encodingTerm.isEmpty()) {
+ return "";
+ }
+ String encoding = encodingTerm.get().asLiteral()
+ .orElseThrow(() -> new FreemarkerException("Encoding must be a literal"))
+ .asStringLiteral()
+ .orElseThrow(() -> new FreemarkerException("Encoding must be a quoted string value")).getValue();
+ return ", utils.WithEncoding(\"" + encoding + "\")";
+ }
+
@Deprecated
public String getSpecialReadBufferReadMethodCall(String logicalName, SimpleTypeReference simpleTypeReference, TypedField field) {
return "/*TODO: migrate me*/" + getReadBufferReadMethodCall(logicalName, simpleTypeReference, null, field);
@@ -407,33 +436,33 @@ public class GoLanguageTemplateHelper extends BaseFreemarkerLanguageTemplateHelp
case UINT:
IntegerTypeReference unsignedIntegerTypeReference = (IntegerTypeReference) simpleTypeReference;
if (unsignedIntegerTypeReference.getSizeInBits() <= 8) {
- return "/*TODO: migrate me*/" + "readBuffer.ReadUint8(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ")";
+ return "/*TODO: migrate me*/" + "readBuffer.ReadUint8(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + getEncodingOption(field) + ")";
}
if (unsignedIntegerTypeReference.getSizeInBits() <= 16) {
- return "/*TODO: migrate me*/" + "readBuffer.ReadUint16(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ")";
+ return "/*TODO: migrate me*/" + "readBuffer.ReadUint16(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + getEncodingOption(field) + ")";
}
if (unsignedIntegerTypeReference.getSizeInBits() <= 32) {
- return "/*TODO: migrate me*/" + "readBuffer.ReadUint32(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ")";
+ return "/*TODO: migrate me*/" + "readBuffer.ReadUint32(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + getEncodingOption(field) + ")";
}
if (unsignedIntegerTypeReference.getSizeInBits() <= 64) {
- return "/*TODO: migrate me*/" + "readBuffer.ReadUint64(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ")";
+ return "/*TODO: migrate me*/" + "readBuffer.ReadUint64(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + getEncodingOption(field) + ")";
}
- return "/*TODO: migrate me*/" + "readBuffer.ReadBigInt(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ")";
+ return "/*TODO: migrate me*/" + "readBuffer.ReadBigInt(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + getEncodingOption(field) + ")";
case INT:
IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
if (integerTypeReference.getSizeInBits() <= 8) {
- return "/*TODO: migrate me*/" + "readBuffer.ReadInt8(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ")";
+ return "/*TODO: migrate me*/" + "readBuffer.ReadInt8(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + getEncodingOption(field) + ")";
}
if (integerTypeReference.getSizeInBits() <= 16) {
- return "/*TODO: migrate me*/" + "readBuffer.ReadInt16(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ")";
+ return "/*TODO: migrate me*/" + "readBuffer.ReadInt16(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + getEncodingOption(field) + ")";
}
if (integerTypeReference.getSizeInBits() <= 32) {
- return "/*TODO: migrate me*/" + "readBuffer.ReadInt32(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ")";
+ return "/*TODO: migrate me*/" + "readBuffer.ReadInt32(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + getEncodingOption(field) + ")";
}
if (integerTypeReference.getSizeInBits() <= 64) {
- return "/*TODO: migrate me*/" + "readBuffer.ReadInt64(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ")";
+ return "/*TODO: migrate me*/" + "readBuffer.ReadInt64(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + getEncodingOption(field) + ")";
}
- return "/*TODO: migrate me*/" + "readBuffer.ReadBigInt(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ")";
+ return "/*TODO: migrate me*/" + "readBuffer.ReadBigInt(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + getEncodingOption(field) + ")";
case FLOAT:
FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
if (floatTypeReference.getSizeInBits() <= 32) {
@@ -689,33 +718,33 @@ public class GoLanguageTemplateHelper extends BaseFreemarkerLanguageTemplateHelp
case UINT:
IntegerTypeReference unsignedIntegerTypeReference = (IntegerTypeReference) simpleTypeReference;
if (unsignedIntegerTypeReference.getSizeInBits() <= 8) {
- return "/*TODO: migrate me*/" + "writeBuffer.WriteUint8(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", uint8(" + fieldName + ")" + writerArgsString + ")";
+ return "/*TODO: migrate me*/" + "writeBuffer.WriteUint8(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", uint8(" + fieldName + ")" + writerArgsString + getEncodingOption(field) + ")";
}
if (unsignedIntegerTypeReference.getSizeInBits() <= 16) {
- return "/*TODO: migrate me*/" + "writeBuffer.WriteUint16(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", uint16(" + fieldName + ")" + writerArgsString + ")";
+ return "/*TODO: migrate me*/" + "writeBuffer.WriteUint16(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", uint16(" + fieldName + ")" + writerArgsString + getEncodingOption(field) + ")";
}
if (unsignedIntegerTypeReference.getSizeInBits() <= 32) {
- return "/*TODO: migrate me*/" + "writeBuffer.WriteUint32(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", uint32(" + fieldName + ")" + writerArgsString + ")";
+ return "/*TODO: migrate me*/" + "writeBuffer.WriteUint32(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", uint32(" + fieldName + ")" + writerArgsString + getEncodingOption(field) + ")";
}
if (unsignedIntegerTypeReference.getSizeInBits() <= 64) {
- return "/*TODO: migrate me*/" + "writeBuffer.WriteUint64(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", uint64(" + fieldName + ")" + writerArgsString + ")";
+ return "/*TODO: migrate me*/" + "writeBuffer.WriteUint64(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", uint64(" + fieldName + ")" + writerArgsString + getEncodingOption(field) + ")";
}
- return "/*TODO: migrate me*/" + "writeBuffer.WriteBigInt(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", " + fieldName + writerArgsString + ")";
+ return "/*TODO: migrate me*/" + "writeBuffer.WriteBigInt(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", " + fieldName + writerArgsString + getEncodingOption(field) + ")";
case INT:
IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
if (integerTypeReference.getSizeInBits() <= 8) {
- return "/*TODO: migrate me*/" + "writeBuffer.WriteInt8(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", int8(" + fieldName + ")" + writerArgsString + ")";
+ return "/*TODO: migrate me*/" + "writeBuffer.WriteInt8(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", int8(" + fieldName + ")" + writerArgsString + getEncodingOption(field) + ")";
}
if (integerTypeReference.getSizeInBits() <= 16) {
- return "/*TODO: migrate me*/" + "writeBuffer.WriteInt16(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", int16(" + fieldName + ")" + writerArgsString + ")";
+ return "/*TODO: migrate me*/" + "writeBuffer.WriteInt16(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", int16(" + fieldName + ")" + writerArgsString + getEncodingOption(field) + ")";
}
if (integerTypeReference.getSizeInBits() <= 32) {
- return "/*TODO: migrate me*/" + "writeBuffer.WriteInt32(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", int32(" + fieldName + ")" + writerArgsString + ")";
+ return "/*TODO: migrate me*/" + "writeBuffer.WriteInt32(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", int32(" + fieldName + ")" + writerArgsString + getEncodingOption(field) + ")";
}
if (integerTypeReference.getSizeInBits() <= 64) {
- return "/*TODO: migrate me*/" + "writeBuffer.WriteInt64(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", int64(" + fieldName + ")" + writerArgsString + ")";
+ return "/*TODO: migrate me*/" + "writeBuffer.WriteInt64(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", int64(" + fieldName + ")" + writerArgsString + getEncodingOption(field) + ")";
}
- return "/*TODO: migrate me*/" + "writeBuffer.WriteBigInt(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", " + fieldName + writerArgsString + ")";
+ return "/*TODO: migrate me*/" + "writeBuffer.WriteBigInt(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", " + fieldName + writerArgsString + getEncodingOption(field) + ")";
case FLOAT:
case UFLOAT:
FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;