summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-07-12 11:20:44 +0100
committerMichael Williamson <mike@zwobble.org>2026-07-12 11:20:44 +0100
commited2fc42b45faa1392342ca7c62e4ad580091bf60 (patch)
treea51bcc6c2f38a645eeed52ae804c6f15dce57b49
parentc33905c4351a02327358284e6de4579a5e311326 (diff)
Support sum types in Java transient-0
-rw-r--r--examples/10-transient-0/output/java-junit/src/test/java/org/zwobble/example/Transient0Tests.java17
-rw-r--r--examples/10-transient-0/src/data.hob13
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java82
3 files changed, 109 insertions, 3 deletions
diff --git a/examples/10-transient-0/output/java-junit/src/test/java/org/zwobble/example/Transient0Tests.java b/examples/10-transient-0/output/java-junit/src/test/java/org/zwobble/example/Transient0Tests.java
index 7d6f7de..e28e926 100644
--- a/examples/10-transient-0/output/java-junit/src/test/java/org/zwobble/example/Transient0Tests.java
+++ b/examples/10-transient-0/output/java-junit/src/test/java/org/zwobble/example/Transient0Tests.java
@@ -19,6 +19,8 @@ import org.zwobble.example.types.data.StructWithInt64;
import org.zwobble.example.types.data.StructWithList;
import org.zwobble.example.types.data.StructWithOption;
import org.zwobble.example.types.data.StructWithString;
+import org.zwobble.example.types.data.VariantOne;
+import org.zwobble.example.types.data.VariantTwo;
public class Transient0Tests {
@Test
@@ -143,6 +145,21 @@ public class Transient0Tests {
);
}
+ @Test
+ public void sumWithVariants() throws IOException {
+ assertRoundTripEncoding(
+ new VariantOne(10),
+ HobgoblinTransient0Data::encodeSumWithVariants,
+ HobgoblinTransient0Data::decodeSumWithVariants
+ );
+
+ assertRoundTripEncoding(
+ new VariantTwo(25),
+ HobgoblinTransient0Data::encodeSumWithVariants,
+ HobgoblinTransient0Data::decodeSumWithVariants
+ );
+ }
+
private <T> void assertRoundTripEncoding(
T value,
Encoder<T> encoder,
diff --git a/examples/10-transient-0/src/data.hob b/examples/10-transient-0/src/data.hob
index f6fa20e..e1d7290 100644
--- a/examples/10-transient-0/src/data.hob
+++ b/examples/10-transient-0/src/data.hob
@@ -43,3 +43,16 @@ enum EnumWithVariants {
variant one;
variant two;
}
+
+sum SumWithVariants {
+ variant VariantOne;
+ variant VariantTwo;
+}
+
+struct VariantOne {
+ field a: Int32;
+}
+
+struct VariantTwo {
+ field a: Int64;
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java
index be04982..0c7d62d 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java
@@ -406,7 +406,75 @@ public class JavaTransient0Generator implements Generator {
}
case TypedSumDefinitionNode sumDefinition -> {
- yield Stream.of();
+ var encodeStatements = List.<JavaBlockStatement>of(new JavaSwitchStatement(
+ new JavaRef(VALUE_NAME),
+ IntStream.range(0, sumDefinition.variants().size())
+ .mapToObj(variantIndex -> {
+ var variant = sumDefinition.variants().get(variantIndex);
+ var variantVariable = JavaIdentifier.of(VALUE_NAME.value() + "$" + variantIndex);
+
+ var statements = new ArrayList<JavaBlockStatement>();
+
+ statements.addAll(generateEncode(
+ new JavaIntegerLiteral(variantIndex),
+ NativeTypes.INT_32
+ ));
+
+ statements.addAll(generateEncode(
+ new JavaRef(variantVariable),
+ variant.type().value()
+ ));
+
+ return new JavaSwitchRule(
+ new JavaCasePattern(
+ this.javaGenerator.generateTypeRef(variant.type().value()),
+ variantVariable
+ ),
+ new JavaBlock(statements)
+ );
+ })
+ .toList()
+ ));
+
+ var decodeStatements = new ArrayList<JavaBlockStatement>();
+
+ var variantTag = JavaIdentifier.of("variantTag");
+
+ decodeStatements.addAll(generateDecode(variantTag, NativeTypes.INT_32));
+
+ decodeStatements.add(new JavaSwitchStatement(
+ new JavaRef(variantTag),
+ IntStream.range(0, sumDefinition.variants().size())
+ .mapToObj(variantIndex -> {
+ var variantType = sumDefinition.variants().get(variantIndex).type().value();
+ var variantVariable = JavaIdentifier.of(VALUE_NAME.value() + "$" + variantIndex);
+
+ var statements = new ArrayList<JavaBlockStatement>();
+
+ statements.addAll(generateDecode(variantVariable, variantType));
+
+ statements.add(new JavaReturn(new JavaRef(variantVariable)));
+
+ return new JavaSwitchRule(
+ new JavaCaseConstant(new JavaIntegerLiteral(variantIndex)),
+ new JavaBlock(statements)
+ );
+ }).toList()
+ ));
+
+ // TODO: handle this more elegantly
+ decodeStatements.add(new JavaReturn(new JavaNullLiteral()));
+
+ yield Stream.of(
+ generateEncodeMethod(
+ sumDefinition.type(),
+ new JavaBlock(encodeStatements)
+ ),
+ generateDecodeMethod(
+ sumDefinition.type(),
+ new JavaBlock(decodeStatements)
+ )
+ );
}
};
}
@@ -493,7 +561,11 @@ public class JavaTransient0Generator implements Generator {
}
case SumType sumType -> {
- throw new UnsupportedOperationException("TODO");
+ yield List.of(generateEncode(
+ value,
+ sumType.namespaceName(),
+ sumType
+ ));
}
case TypeLevelValueType typeLevelValueType -> {
@@ -557,7 +629,11 @@ public class JavaTransient0Generator implements Generator {
}
case SumType sumType -> {
- throw new UnsupportedOperationException("TODO");
+ yield List.of(generateDecode(
+ target,
+ sumType.namespaceName(),
+ sumType
+ ));
}
case TypeLevelValueType typeLevelValueType -> {