aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-03-22 18:25:49 +0000
committerMichael Williamson <mike@zwobble.org>2026-03-22 18:25:49 +0000
commit0a6b38ca7ee956cab5818c195856d5c159966f7a (patch)
tree760bb0e88b5e83a2a44826ed032d580e334fd82a /src
parented1c39334aaf4635119532e9ba6098a46843321a (diff)
Serialize Patio data values to flatbuffers
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/shedlang/compiler/patio/serialization/PatioToFlatbuffers.java171
-rw-r--r--src/test/java/org/shedlang/compiler/patio/serialization/PatioSerializationTests.java99
-rw-r--r--src/test/java/org/shedlang/compiler/patio/serialization/PatioToFlatbuffersTests.java20
-rw-r--r--src/test/java/org/shedlang/compiler/patio/serialization/PatioToProtobufTests.java105
4 files changed, 297 insertions, 98 deletions
diff --git a/src/main/java/org/shedlang/compiler/patio/serialization/PatioToFlatbuffers.java b/src/main/java/org/shedlang/compiler/patio/serialization/PatioToFlatbuffers.java
index 6e5545a5..7eaae88e 100644
--- a/src/main/java/org/shedlang/compiler/patio/serialization/PatioToFlatbuffers.java
+++ b/src/main/java/org/shedlang/compiler/patio/serialization/PatioToFlatbuffers.java
@@ -323,6 +323,177 @@ public class PatioToFlatbuffers {
};
}
+ // == Data values ==
+
+ public static int serializeDataValue(FlatBufferBuilder builder, PatioDataValue value) {
+ return switch (value) {
+ case PatioDataValueArray array -> {
+ var elementLayoutFbs = serializeDataLayout(builder, array.elementLayout());
+
+ var elementsOffsetsFbs = array.elements().stream()
+ .mapToInt(element -> serializeDataValue(builder, element))
+ .toArray();
+ var elementsVectorFbs = PatioDataValueArrayFbs.createElementsVector(builder, elementsOffsetsFbs);
+
+ PatioDataValueArrayFbs.startPatioDataValueArrayFbs(builder);
+ PatioDataValueArrayFbs.addElementLayout(builder, elementLayoutFbs);
+ PatioDataValueArrayFbs.addElements(builder, elementsVectorFbs);
+ var arrayFbs = PatioDataValueArrayFbs.endPatioDataValueArrayFbs(builder);
+
+ PatioDataValueFbs.startPatioDataValueFbs(builder);
+ PatioDataValueFbs.addValueType(builder, PatioDataValueValueFbs.PatioDataValueArrayFbs);
+ PatioDataValueFbs.addValue(builder, arrayFbs);
+ yield PatioDataValueFbs.endPatioDataValueFbs(builder);
+ }
+
+ case PatioDataValueBool bool -> {
+ PatioDataValueBoolFbs.startPatioDataValueBoolFbs(builder);
+ PatioDataValueBoolFbs.addValue(builder, bool.value());
+ var boolFbs = PatioDataValueBoolFbs.endPatioDataValueBoolFbs(builder);
+
+ PatioDataValueFbs.startPatioDataValueFbs(builder);
+ PatioDataValueFbs.addValueType(builder, PatioDataValueValueFbs.PatioDataValueBoolFbs);
+ PatioDataValueFbs.addValue(builder, boolFbs);
+ yield PatioDataValueFbs.endPatioDataValueFbs(builder);
+ }
+
+ case PatioDataValueByte byte_ -> {
+ PatioDataValueByteFbs.startPatioDataValueByteFbs(builder);
+ PatioDataValueByteFbs.addValue(builder, byte_.value());
+ var byteFbs = PatioDataValueByteFbs.endPatioDataValueByteFbs(builder);
+
+ PatioDataValueFbs.startPatioDataValueFbs(builder);
+ PatioDataValueFbs.addValueType(builder, PatioDataValueValueFbs.PatioDataValueByteFbs);
+ PatioDataValueFbs.addValue(builder, byteFbs);
+ yield PatioDataValueFbs.endPatioDataValueFbs(builder);
+ }
+
+ case PatioDataValueDataPtr dataPtr -> {
+ var dataPtrValueFbs = serializeDataPtrValue(builder, dataPtr.value());
+
+ PatioDataValueDataPtrFbs.startPatioDataValueDataPtrFbs(builder);
+ PatioDataValueDataPtrFbs.addValue(builder, dataPtrValueFbs);
+ var dataPtrFbs = PatioDataValueDataPtrFbs.endPatioDataValueDataPtrFbs(builder);
+
+ PatioDataValueFbs.startPatioDataValueFbs(builder);
+ PatioDataValueFbs.addValueType(builder, PatioDataValueValueFbs.PatioDataValueDataPtrFbs);
+ PatioDataValueFbs.addValue(builder, dataPtrFbs);
+ yield PatioDataValueFbs.endPatioDataValueFbs(builder);
+ }
+
+ case PatioDataValueInt int_ -> {
+ var intValueFbs = serializeIntValue(builder, int_.value());
+
+ PatioDataValueIntFbs.startPatioDataValueIntFbs(builder);
+ PatioDataValueIntFbs.addValue(builder, intValueFbs);
+ var intFbs = PatioDataValueIntFbs.endPatioDataValueIntFbs(builder);
+
+ PatioDataValueFbs.startPatioDataValueFbs(builder);
+ PatioDataValueFbs.addValueType(builder, PatioDataValueValueFbs.PatioDataValueIntFbs);
+ PatioDataValueFbs.addValue(builder, intFbs);
+ yield PatioDataValueFbs.endPatioDataValueFbs(builder);
+ }
+
+ case PatioDataValueInt32 int32 -> {
+ var intValueFbs = serializeIntValue(builder, int32.value());
+
+ PatioDataValueInt32Fbs.startPatioDataValueInt32Fbs(builder);
+ PatioDataValueInt32Fbs.addValue(builder, intValueFbs);
+ var int32Fbs = PatioDataValueInt32Fbs.endPatioDataValueInt32Fbs(builder);
+
+ PatioDataValueFbs.startPatioDataValueFbs(builder);
+ PatioDataValueFbs.addValueType(builder, PatioDataValueValueFbs.PatioDataValueInt32Fbs);
+ PatioDataValueFbs.addValue(builder, int32Fbs);
+ yield PatioDataValueFbs.endPatioDataValueFbs(builder);
+ }
+
+ case PatioDataValueStruct struct -> {
+ var elementsOffsetsFbs = struct.elements().stream()
+ .mapToInt(element -> serializeDataValue(builder, element))
+ .toArray();
+ var elementsVectorFbs = PatioDataValueStructFbs.createElementsVector(builder, elementsOffsetsFbs);
+
+ PatioDataValueStructFbs.startPatioDataValueStructFbs(builder);
+ PatioDataValueStructFbs.addElements(builder, elementsVectorFbs);
+ var structFbs = PatioDataValueStructFbs.endPatioDataValueStructFbs(builder);
+
+ PatioDataValueFbs.startPatioDataValueFbs(builder);
+ PatioDataValueFbs.addValueType(builder, PatioDataValueValueFbs.PatioDataValueStructFbs);
+ PatioDataValueFbs.addValue(builder, structFbs);
+ yield PatioDataValueFbs.endPatioDataValueFbs(builder);
+ }
+ };
+ }
+
+ public static PatioDataValue deserializeDataValue(PatioDataValueFbs valueFbs) {
+ return switch (valueFbs.valueType()) {
+ case PatioDataValueValueFbs.PatioDataValueArrayFbs -> {
+ var arrayFbs = (PatioDataValueArrayFbs) valueFbs.value(new PatioDataValueArrayFbs());
+
+ var elementLayout = deserializeDataLayout(arrayFbs.elementLayout());
+
+ var elements = mapVector(
+ arrayFbs::elements,
+ arrayFbs.elementsLength(),
+ PatioToFlatbuffers::deserializeDataValue
+ );
+
+ yield new PatioDataValueArray(elementLayout, elements);
+ }
+
+ case PatioDataValueValueFbs.PatioDataValueBoolFbs -> {
+ var boolFbs = (PatioDataValueBoolFbs) valueFbs.value(new PatioDataValueBoolFbs());
+
+ yield new PatioDataValueBool(boolFbs.value());
+ }
+
+ case PatioDataValueValueFbs.PatioDataValueByteFbs -> {
+ var byteFbs = (PatioDataValueByteFbs) valueFbs.value(new PatioDataValueByteFbs());
+
+ yield new PatioDataValueByte((byte) byteFbs.value());
+ }
+
+ case PatioDataValueValueFbs.PatioDataValueDataPtrFbs -> {
+ var dataPtrFbs = (PatioDataValueDataPtrFbs) valueFbs.value(new PatioDataValueDataPtrFbs());
+
+ var value = deserializeDataPtrValue(dataPtrFbs.value());
+
+ yield new PatioDataValueDataPtr(value);
+ }
+
+ case PatioDataValueValueFbs.PatioDataValueIntFbs -> {
+ var intFbs = (PatioDataValueIntFbs) valueFbs.value(new PatioDataValueIntFbs());
+
+ var value = deserializeIntValue(intFbs.value());
+
+ yield new PatioDataValueInt(value);
+ }
+
+ case PatioDataValueValueFbs.PatioDataValueInt32Fbs -> {
+ var int32Fbs = (PatioDataValueInt32Fbs) valueFbs.value(new PatioDataValueInt32Fbs());
+
+ var value = deserializeIntValue(int32Fbs.value());
+
+ yield new PatioDataValueInt32(value);
+ }
+
+ case PatioDataValueValueFbs.PatioDataValueStructFbs -> {
+ var structFbs = (PatioDataValueStructFbs) valueFbs.value(new PatioDataValueStructFbs());
+
+ var elements = mapVector(
+ structFbs::elements,
+ structFbs.elementsLength(),
+ PatioToFlatbuffers::deserializeDataValue
+ );
+
+ yield new PatioDataValueStruct(elements);
+ }
+
+ default ->
+ throw new UnsupportedOperationException("TODO");
+ };
+ }
+
// == Flatbuffers ==
private static <T, R> List<R> mapVector(Function<Integer, T> get, int length, Function<T, R> map) {
diff --git a/src/test/java/org/shedlang/compiler/patio/serialization/PatioSerializationTests.java b/src/test/java/org/shedlang/compiler/patio/serialization/PatioSerializationTests.java
index 791743c0..14d47932 100644
--- a/src/test/java/org/shedlang/compiler/patio/serialization/PatioSerializationTests.java
+++ b/src/test/java/org/shedlang/compiler/patio/serialization/PatioSerializationTests.java
@@ -2,10 +2,7 @@ package org.shedlang.compiler.patio.serialization;
import org.junit.jupiter.api.Test;
import org.shedlang.compiler.patio.instructions.Patio;
-import org.shedlang.compiler.patio.types.PatioDataLayout;
-import org.shedlang.compiler.patio.types.PatioDataLayouts;
-import org.shedlang.compiler.patio.types.PatioType;
-import org.shedlang.compiler.patio.types.PatioTypes;
+import org.shedlang.compiler.patio.types.*;
import org.shedlang.compiler.patio.values.PatioDataPtrValue;
import org.shedlang.compiler.patio.values.PatioIntValue;
@@ -265,4 +262,98 @@ public abstract class PatioSerializationTests {
assertThat(deserializedLayout, equalTo(layout));
}
+
+ // == Data values ==
+
+ protected abstract PatioDataValue deserializeDataValue(byte[] buffer);
+ protected abstract byte[] serializeDataValue(PatioDataValue value);
+
+
+ @Test
+ public void canSerializeDataValueArray() {
+ var value = PatioDataValues.array(
+ PatioDataLayouts.BYTE,
+ List.of(
+ PatioDataValues.byte_(0x01),
+ PatioDataValues.byte_(0x02),
+ PatioDataValues.byte_(0x03)
+ )
+ );
+
+ var deserializedValue = deserializeDataValue(
+ serializeDataValue(value)
+ );
+
+ assertThat(deserializedValue, equalTo(value));
+ }
+
+ @Test
+ public void canSerializeDataValueBool() {
+ var value = PatioDataValues.bool(true);
+
+ var deserializedValue = deserializeDataValue(
+ serializeDataValue(value)
+ );
+
+ assertThat(deserializedValue, equalTo(value));
+ }
+
+ @Test
+ public void canSerializeDataValueByte() {
+ var value = PatioDataValues.byte_(0xc8);
+
+ var deserializedValue = deserializeDataValue(
+ serializeDataValue(value)
+ );
+
+ assertThat(deserializedValue, equalTo(value));
+ }
+
+ @Test
+ public void canSerializeDataValueDataPtr() {
+ var value = PatioDataValues.dataPtrNull();
+
+ var deserializedValue = deserializeDataValue(
+ serializeDataValue(value)
+ );
+
+ assertThat(deserializedValue, equalTo(value));
+ }
+
+ @Test
+ public void canSerializeDataValueInt() {
+ var value = PatioDataValues.int_(42);
+
+ var deserializedValue = deserializeDataValue(
+ serializeDataValue(value)
+ );
+
+ assertThat(deserializedValue, equalTo(value));
+ }
+
+ @Test
+ public void canSerializeDataValueInt32() {
+ var value = PatioDataValues.int32(42);
+
+ var deserializedValue = deserializeDataValue(
+ serializeDataValue(value)
+ );
+
+ assertThat(deserializedValue, equalTo(value));
+ }
+
+ @Test
+ public void canSerializeDataValueStruct() {
+ var value = PatioDataValues.struct(List.of(
+ PatioDataValues.byte_(0x01),
+ PatioDataValues.byte_(0x02),
+ PatioDataValues.byte_(0x03)
+ ));
+
+ var deserializedValue = deserializeDataValue(
+ serializeDataValue(value)
+ );
+
+ assertThat(deserializedValue, equalTo(value));
+ }
}
diff --git a/src/test/java/org/shedlang/compiler/patio/serialization/PatioToFlatbuffersTests.java b/src/test/java/org/shedlang/compiler/patio/serialization/PatioToFlatbuffersTests.java
index 2f6fdede..e8c5eaa8 100644
--- a/src/test/java/org/shedlang/compiler/patio/serialization/PatioToFlatbuffersTests.java
+++ b/src/test/java/org/shedlang/compiler/patio/serialization/PatioToFlatbuffersTests.java
@@ -1,11 +1,9 @@
package org.shedlang.compiler.patio.serialization;
import com.google.flatbuffers.FlatBufferBuilder;
-import org.shedlang.compiler.patio.flatbuffers.PatioDataLayoutFbs;
-import org.shedlang.compiler.patio.flatbuffers.PatioDataPtrValueFbs;
-import org.shedlang.compiler.patio.flatbuffers.PatioIntValueFbs;
-import org.shedlang.compiler.patio.flatbuffers.PatioTypeFbs;
+import org.shedlang.compiler.patio.flatbuffers.*;
import org.shedlang.compiler.patio.types.PatioDataLayout;
+import org.shedlang.compiler.patio.types.PatioDataValue;
import org.shedlang.compiler.patio.types.PatioType;
import org.shedlang.compiler.patio.values.PatioDataPtrValue;
import org.shedlang.compiler.patio.values.PatioIntValue;
@@ -68,4 +66,18 @@ public class PatioToFlatbuffersTests extends PatioSerializationTests {
var valueFbs = PatioDataLayoutFbs.getRootAsPatioDataLayoutFbs(ByteBuffer.wrap(buffer));
return PatioToFlatbuffers.deserializeDataLayout(valueFbs);
}
+
+ @Override
+ protected byte[] serializeDataValue(PatioDataValue value) {
+ var builder = new FlatBufferBuilder();
+ var valueFbs = PatioToFlatbuffers.serializeDataValue(builder, value);
+ builder.finish(valueFbs);
+ return builder.sizedByteArray();
+ }
+
+ @Override
+ protected PatioDataValue deserializeDataValue(byte[] buffer) {
+ var valueFbs = PatioDataValueFbs.getRootAsPatioDataValueFbs(ByteBuffer.wrap(buffer));
+ return PatioToFlatbuffers.deserializeDataValue(valueFbs);
+ }
}
diff --git a/src/test/java/org/shedlang/compiler/patio/serialization/PatioToProtobufTests.java b/src/test/java/org/shedlang/compiler/patio/serialization/PatioToProtobufTests.java
index 44334435..a57b7810 100644
--- a/src/test/java/org/shedlang/compiler/patio/serialization/PatioToProtobufTests.java
+++ b/src/test/java/org/shedlang/compiler/patio/serialization/PatioToProtobufTests.java
@@ -79,6 +79,21 @@ public class PatioToProtobufTests extends PatioSerializationTests {
}
}
+ @Override
+ protected byte[] serializeDataValue(PatioDataValue value) {
+ return PatioToProtobuf.serializeDataValue(value).toByteArray();
+ }
+
+ @Override
+ protected PatioDataValue deserializeDataValue(byte[] buffer) {
+ try {
+ var valueProtobuf = PatioProtobuf.PatioDataValue.parseFrom(buffer);
+ return PatioToProtobuf.deserializeDataValue(valueProtobuf);
+ } catch (InvalidProtocolBufferException exception) {
+ throw new RuntimeException(exception);
+ }
+ }
+
// == Compilation unit ==
@Test
@@ -780,94 +795,4 @@ public class PatioToProtobufTests extends PatioSerializationTests {
assertThat(deserializedOperand, equalTo(operand));
}
-
- // == Data values ==
-
- @Test
- public void canSerializeDataValueArray() {
- var value = PatioDataValues.array(
- PatioDataLayouts.BYTE,
- List.of(
- PatioDataValues.byte_(0x01),
- PatioDataValues.byte_(0x02),
- PatioDataValues.byte_(0x03)
- )
- );
-
- var deserializedValue = PatioToProtobuf.deserializeDataValue(
- PatioToProtobuf.serializeDataValue(value)
- );
-
- assertThat(deserializedValue, equalTo(value));
- }
-
- @Test
- public void canSerializeDataValueBool() {
- var value = PatioDataValues.bool(true);
-
- var deserializedValue = PatioToProtobuf.deserializeDataValue(
- PatioToProtobuf.serializeDataValue(value)
- );
-
- assertThat(deserializedValue, equalTo(value));
- }
-
- @Test
- public void canSerializeDataValueByte() {
- var value = PatioDataValues.byte_(0xc8);
-
- var deserializedValue = PatioToProtobuf.deserializeDataValue(
- PatioToProtobuf.serializeDataValue(value)
- );
-
- assertThat(deserializedValue, equalTo(value));
- }
-
- @Test
- public void canSerializeDataValueDataPtr() {
- var value = PatioDataValues.dataPtrNull();
-
- var deserializedValue = PatioToProtobuf.deserializeDataValue(
- PatioToProtobuf.serializeDataValue(value)
- );
-
- assertThat(deserializedValue, equalTo(value));
- }
-
- @Test
- public void canSerializeDataValueInt() {
- var value = PatioDataValues.int_(42);
-
- var deserializedValue = PatioToProtobuf.deserializeDataValue(
- PatioToProtobuf.serializeDataValue(value)
- );
-
- assertThat(deserializedValue, equalTo(value));
- }
-
- @Test
- public void canSerializeDataValueInt32() {
- var value = PatioDataValues.int32(42);
-
- var deserializedValue = PatioToProtobuf.deserializeDataValue(
- PatioToProtobuf.serializeDataValue(value)
- );
-
- assertThat(deserializedValue, equalTo(value));
- }
-
- @Test
- public void canSerializeDataValueStruct() {
- var value = PatioDataValues.struct(List.of(
- PatioDataValues.byte_(0x01),
- PatioDataValues.byte_(0x02),
- PatioDataValues.byte_(0x03)
- ));
-
- var deserializedValue = PatioToProtobuf.deserializeDataValue(
- PatioToProtobuf.serializeDataValue(value)
- );
-
- assertThat(deserializedValue, equalTo(value));
- }
}