From 8430d69e1df2e9062c8fa25c5b0584966794855e Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 22 Mar 2026 17:56:34 +0000 Subject: Serialize Patio int values to flatbuffers --- .../patio/serialization/PatioToFlatbuffers.java | 91 +++++++++++++++++++++- .../serialization/PatioSerializationTests.java | 50 ++++++++++++ .../serialization/PatioToFlatbuffersTests.java | 16 ++++ .../patio/serialization/PatioToProtobufTests.java | 62 ++++----------- 4 files changed, 170 insertions(+), 49 deletions(-) (limited to 'src') 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 58207bda..aab63bad 100644 --- a/src/main/java/org/shedlang/compiler/patio/serialization/PatioToFlatbuffers.java +++ b/src/main/java/org/shedlang/compiler/patio/serialization/PatioToFlatbuffers.java @@ -1,11 +1,10 @@ package org.shedlang.compiler.patio.serialization; import com.google.flatbuffers.FlatBufferBuilder; +import com.google.flatbuffers.IntVector; import org.shedlang.compiler.patio.flatbuffers.*; import org.shedlang.compiler.patio.types.*; -import org.shedlang.compiler.patio.values.PatioDataPtrValue; -import org.shedlang.compiler.patio.values.PatioDataPtrValueDataElement; -import org.shedlang.compiler.patio.values.PatioDataPtrValueNull; +import org.shedlang.compiler.patio.values.*; import java.util.ArrayList; import java.util.List; @@ -60,6 +59,76 @@ public class PatioToFlatbuffers { }; } + // == Int values == + + public static int serializeIntValue(FlatBufferBuilder builder, PatioIntValue value) { + return switch (value) { + case PatioIntValueByteOffsetOf byteOffsetOf -> { + var layoutFbs = serializeDataLayout(builder, byteOffsetOf.layout()); + var offsetFbs = PatioIntValueByteOffsetOfFbs.createOffsetVector( + builder, + intListToLongArray(byteOffsetOf.offset()) + ); + + var byteOffsetOfFbs = PatioIntValueByteOffsetOfFbs.createPatioIntValueByteOffsetOfFbs( + builder, + layoutFbs, + offsetFbs + ); + + PatioIntValueFbs.startPatioIntValueFbs(builder); + PatioIntValueFbs.addValueType(builder, PatioIntValueValueFbs.PatioIntValueByteOffsetOfFbs); + PatioIntValueFbs.addValue(builder, byteOffsetOfFbs); + yield PatioIntValueFbs.endPatioIntValueFbs(builder); + } + + case PatioIntValueByteSizeOf byteSizeOf -> { + var layoutFbs = serializeDataLayout(builder, byteSizeOf.layout()); + + var byteSizeOfFbs = PatioIntValueByteSizeOfFbs.createPatioIntValueByteSizeOfFbs(builder, layoutFbs); + + PatioIntValueFbs.startPatioIntValueFbs(builder); + PatioIntValueFbs.addValueType(builder, PatioIntValueValueFbs.PatioIntValueByteSizeOfFbs); + PatioIntValueFbs.addValue(builder, byteSizeOfFbs); + yield PatioIntValueFbs.endPatioIntValueFbs(builder); + } + + case PatioIntValueLiteral literal -> { + var literalFbs = PatioIntValueLiteralFbs.createPatioIntValueLiteralFbs(builder, literal.value()); + + PatioIntValueFbs.startPatioIntValueFbs(builder); + PatioIntValueFbs.addValueType(builder, PatioIntValueValueFbs.PatioIntValueLiteralFbs); + PatioIntValueFbs.addValue(builder, literalFbs); + yield PatioIntValueFbs.endPatioIntValueFbs(builder); + } + }; + } + + public static PatioIntValue deserializeIntValue(PatioIntValueFbs valueFbs) { + return switch (valueFbs.valueType()) { + case PatioIntValueValueFbs.PatioIntValueByteOffsetOfFbs -> { + var byteOffsetOfFbs = (PatioIntValueByteOffsetOfFbs) valueFbs.value(new PatioIntValueByteOffsetOfFbs()); + var layout = deserializeDataLayout(byteOffsetOfFbs.layout()); + var offset = deserializeListOfInts(byteOffsetOfFbs.offsetVector()); + yield new PatioIntValueByteOffsetOf(layout, offset); + } + + case PatioIntValueValueFbs.PatioIntValueByteSizeOfFbs -> { + var byteSizeOfFbs = (PatioIntValueByteSizeOfFbs) valueFbs.value(new PatioIntValueByteSizeOfFbs()); + var layout = deserializeDataLayout(byteSizeOfFbs.layout()); + yield new PatioIntValueByteSizeOf(layout); + } + + case PatioIntValueValueFbs.PatioIntValueLiteralFbs -> { + var literalFbs = (PatioIntValueLiteralFbs) valueFbs.value(new PatioIntValueLiteralFbs()); + yield new PatioIntValueLiteral(literalFbs.value()); + } + + default -> + throw new UnsupportedOperationException("TODO"); + }; + } + // == Data layouts == public static int serializeDataLayout( @@ -186,4 +255,20 @@ public class PatioToFlatbuffers { } return result; } + + private static long[] intListToLongArray(List list) { + var array = new long[list.size()]; + for (var index = 0; index < list.size(); index++) { + array[index] = list.get(index); + } + return array; + } + + private static List deserializeListOfInts(IntVector vector) { + var result = new ArrayList(); + for (var index = 0; index < vector.length(); index++) { + result.add(vector.get(index)); + } + return result; + } } 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 3ed5ae0c..b68d89b7 100644 --- a/src/test/java/org/shedlang/compiler/patio/serialization/PatioSerializationTests.java +++ b/src/test/java/org/shedlang/compiler/patio/serialization/PatioSerializationTests.java @@ -5,6 +5,7 @@ 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.values.PatioDataPtrValue; +import org.shedlang.compiler.patio.values.PatioIntValue; import java.util.List; @@ -39,6 +40,55 @@ public abstract class PatioSerializationTests { assertThat(deserializedDataPtrValue, equalTo(dataPtrValue)); } + // == Int values == + + protected abstract PatioIntValue deserializeIntValue(byte[] buffer); + protected abstract byte[] serializeIntValue(PatioIntValue value); + + @Test + public void canSerializeIntValueByteOffsetOf() { + var intValue = Patio.intValueByteOffsetOf( + PatioDataLayouts.struct(List.of( + PatioDataLayouts.INT, + PatioDataLayouts.BYTE + )), + List.of(1, 2) + ); + + var deserializedIntValue = deserializeIntValue( + serializeIntValue(intValue) + ); + + assertThat(deserializedIntValue, equalTo(intValue)); + } + + @Test + public void canSerializeIntValueByteSizeOf() { + var intValue = Patio.intValueByteSizeOf( + PatioDataLayouts.struct(List.of( + PatioDataLayouts.INT, + PatioDataLayouts.BYTE + )) + ); + + var deserializedIntValue = deserializeIntValue( + serializeIntValue(intValue) + ); + + assertThat(deserializedIntValue, equalTo(intValue)); + } + + @Test + public void canSerializeIntValueLiteral() { + var intValue = Patio.intValueLiteral(42); + + var deserializedIntValue = deserializeIntValue( + serializeIntValue(intValue) + ); + + assertThat(deserializedIntValue, equalTo(intValue)); + } + // == Data layouts == protected abstract PatioDataLayout deserializeDataLayout(byte[] buffer); 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 eacb36cb..3c787404 100644 --- a/src/test/java/org/shedlang/compiler/patio/serialization/PatioToFlatbuffersTests.java +++ b/src/test/java/org/shedlang/compiler/patio/serialization/PatioToFlatbuffersTests.java @@ -3,8 +3,10 @@ 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.types.PatioDataLayout; import org.shedlang.compiler.patio.values.PatioDataPtrValue; +import org.shedlang.compiler.patio.values.PatioIntValue; import java.nio.ByteBuffer; @@ -23,6 +25,20 @@ public class PatioToFlatbuffersTests extends PatioSerializationTests { return PatioToFlatbuffers.deserializeDataPtrValue(valueFbs); } + @Override + protected byte[] serializeIntValue(PatioIntValue value) { + var builder = new FlatBufferBuilder(); + var valueFbs = PatioToFlatbuffers.serializeIntValue(builder, value); + builder.finish(valueFbs); + return builder.sizedByteArray(); + } + + @Override + protected PatioIntValue deserializeIntValue(byte[] buffer) { + var valueFbs = PatioIntValueFbs.getRootAsPatioIntValueFbs(ByteBuffer.wrap(buffer)); + return PatioToFlatbuffers.deserializeIntValue(valueFbs); + } + @Override protected byte[] serializeDataLayout(PatioDataLayout value) { var builder = new FlatBufferBuilder(); 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 a112af5c..18a92f59 100644 --- a/src/test/java/org/shedlang/compiler/patio/serialization/PatioToProtobufTests.java +++ b/src/test/java/org/shedlang/compiler/patio/serialization/PatioToProtobufTests.java @@ -12,6 +12,7 @@ import org.shedlang.compiler.patio.types.PatioDataLayouts; import org.shedlang.compiler.patio.types.PatioDataValues; import org.shedlang.compiler.patio.types.PatioTypes; import org.shedlang.compiler.patio.values.PatioDataPtrValue; +import org.shedlang.compiler.patio.values.PatioIntValue; import org.shedlang.compiler.sources.Sources; import java.util.List; @@ -36,6 +37,21 @@ public class PatioToProtobufTests extends PatioSerializationTests { } } + @Override + protected byte[] serializeIntValue(PatioIntValue value) { + return PatioToProtobuf.serializeIntValue(value).toByteArray(); + } + + @Override + protected PatioIntValue deserializeIntValue(byte[] buffer) { + try { + var valueProtobuf = PatioProtobuf.PatioIntValue.parseFrom(buffer); + return PatioToProtobuf.deserializeIntValue(valueProtobuf); + } catch (InvalidProtocolBufferException exception) { + throw new RuntimeException(exception); + } + } + @Override protected byte[] serializeDataLayout(PatioDataLayout value) { return PatioToProtobuf.serializeDataLayout(value).toByteArray(); @@ -753,52 +769,6 @@ public class PatioToProtobufTests extends PatioSerializationTests { assertThat(deserializedOperand, equalTo(operand)); } - // == Int values == - - @Test - public void canSerializeIntValueByteOffsetOf() { - var intValue = Patio.intValueByteOffsetOf( - PatioDataLayouts.struct(List.of( - PatioDataLayouts.INT, - PatioDataLayouts.BYTE - )), - List.of(1, 2) - ); - - var deserializedIntValue = PatioToProtobuf.deserializeIntValue( - PatioToProtobuf.serializeIntValue(intValue) - ); - - assertThat(deserializedIntValue, equalTo(intValue)); - } - - @Test - public void canSerializeIntValueByteSizeOf() { - var intValue = Patio.intValueByteSizeOf( - PatioDataLayouts.struct(List.of( - PatioDataLayouts.INT, - PatioDataLayouts.BYTE - )) - ); - - var deserializedIntValue = PatioToProtobuf.deserializeIntValue( - PatioToProtobuf.serializeIntValue(intValue) - ); - - assertThat(deserializedIntValue, equalTo(intValue)); - } - - @Test - public void canSerializeIntValueLiteral() { - var intValue = Patio.intValueLiteral(42); - - var deserializedIntValue = PatioToProtobuf.deserializeIntValue( - PatioToProtobuf.serializeIntValue(intValue) - ); - - assertThat(deserializedIntValue, equalTo(intValue)); - } - // == Types == @Test -- cgit v1.2.3