diff --git a/compiler/src/main/cpp/capnpc-java.c++ b/compiler/src/main/cpp/capnpc-java.c++ index b4fd948..71886b3 100644 --- a/compiler/src/main/cpp/capnpc-java.c++ +++ b/compiler/src/main/cpp/capnpc-java.c++ @@ -692,6 +692,27 @@ private: } } + kj::String makeListFactoryArg(schema::Type::Reader type) { + auto elementType = type.getList().getElementType(); + switch (elementType.which()) { + case schema::Type::STRUCT: + return kj::str("new org.capnproto.StructList.Factory<", + typeName(elementType, kj::str(".Builder")),", ", + typeName(elementType, kj::str(".Reader")), ">(", + typeName(elementType, kj::str("")), ".factory)"); + case schema::Type::LIST: + return makeListListFactoryArg(elementType); + case schema::Type::ENUM: + return kj::str("new org.capnproto.EnumList.Factory<", + typeName(elementType), ">(", + typeName(elementType, kj::str("")), + ".values())"); + default: + return kj::str(typeName(type, kj::str(".factory"))); + } + + } + FieldText makeFieldText(kj::StringPtr scope, StructSchema::Field field, int indent) { auto proto = field.getProto(); kj::String titleCase = toTitleCase(proto.getName()); @@ -1363,19 +1384,23 @@ private: return ConstText { true, kj::strTree(spaces(indent), - "public static final ", typeName_, ".Reader ", upperCase, "=\n", + "public static final ", typeName_, ".Reader ", upperCase, " =\n", spaces(indent), " new ", typeName_, ".Reader((new org.capnproto.PointerReader(Schemas.b_", kj::hex(proto.getId()), ",", schema.getValueSchemaOffset(), ",0x7fffffff)).getStruct());\n") }; } case schema::Value::LIST: { - kj::String constType = kj::strTree( - "::capnp::_::ConstList<", typeName(type.getList().getElementType()), ">").flatten(); + kj::String constType = typeName(type, kj::str(".Reader")).flatten();; return ConstText { true, - kj::strTree("const ", constType, ' ', scope, upperCase, "(::capnp::schemas::b_", - kj::hex(proto.getId()), ".words + ", schema.getValueSchemaOffset(), ");\n") + kj::strTree( + spaces(indent), + "public static final ", constType, ' ', upperCase, " =\n", + spaces(indent), " (", + "new org.capnproto.AnyPointer.Reader(new org.capnproto.PointerReader(Schemas.b_", + kj::hex(proto.getId()), ",", schema.getValueSchemaOffset(), ",0x7fffffff)).getAsList(", + makeListFactoryArg(type), "));\n") }; } diff --git a/compiler/src/test/scala/org/capnproto/EncodingTest.scala b/compiler/src/test/scala/org/capnproto/EncodingTest.scala index 8f3282f..4b03865 100644 --- a/compiler/src/test/scala/org/capnproto/EncodingTest.scala +++ b/compiler/src/test/scala/org/capnproto/EncodingTest.scala @@ -156,6 +156,34 @@ class EncodingSuite extends FunSuite { // ... } + TestConstants.VOID_LIST_CONST.size() should equal (6); + + { + val listReader = TestConstants.BOOL_LIST_CONST; + listReader.size() should equal (4); + listReader.get(0) should equal (true); + listReader.get(1) should equal (false); + listReader.get(2) should equal (false); + listReader.get(3) should equal (true); + } + + // ... + { + val listReader = TestConstants.TEXT_LIST_CONST; + listReader.size() should equal(3); + listReader.get(0).toString() should equal ("plugh"); + listReader.get(1).toString() should equal ("xyzzy"); + listReader.get(2).toString() should equal ("thud"); + } + + { + val listReader = TestConstants.STRUCT_LIST_CONST; + listReader.size() should equal(3); + listReader.get(0).getTextField().toString() should equal ("structlist 1"); + listReader.get(1).getTextField().toString() should equal ("structlist 2"); + listReader.get(2).getTextField().toString() should equal ("structlist 3"); + } + } test("GlobalConstants") { diff --git a/compiler/src/test/schema/test.capnp b/compiler/src/test/schema/test.capnp index 0293266..c7ba359 100644 --- a/compiler/src/test/schema/test.capnp +++ b/compiler/src/test/schema/test.capnp @@ -313,8 +313,28 @@ struct TestConstants { # interfaceList can't have a default ); -# ... const enumConst :TestEnum = corge; + + const voidListConst :List(Void) = [void, void, void, void, void, void]; + const boolListConst :List(Bool) = [true, false, false, true]; + const int8ListConst :List(Int8) = [111, -111]; + const int16ListConst :List(Int16) = [11111, -11111]; + const int32ListConst :List(Int32) = [111111111, -111111111]; + const int64ListConst :List(Int64) = [1111111111111111111, -1111111111111111111]; + const uint8ListConst :List(UInt8) = [111, 222] ; + const uint16ListConst :List(UInt16) = [33333, 44444]; + const uint32ListConst :List(UInt32) = [3333333333]; + const uint64ListConst :List(UInt64) = [11111111111111111111]; + const float32ListConst :List(Float32) = [5555.5, inf, -inf, nan]; + const float64ListConst :List(Float64) = [7777.75, inf, -inf, nan]; + const textListConst :List(Text) = ["plugh", "xyzzy", "thud"]; + const dataListConst :List(Data) = ["oops", "exhausted", "rfc3092"]; + const structListConst :List(TestAllTypes) = [ + (textField = "structlist 1"), + (textField = "structlist 2"), + (textField = "structlist 3")]; + const enumListConst :List(TestEnum) = [foo, garply]; + } const globalInt :UInt32 = 12345; \ No newline at end of file diff --git a/runtime/src/main/java/org/capnproto/AnyPointer.java b/runtime/src/main/java/org/capnproto/AnyPointer.java index 1314ba2..bd49017 100644 --- a/runtime/src/main/java/org/capnproto/AnyPointer.java +++ b/runtime/src/main/java/org/capnproto/AnyPointer.java @@ -12,6 +12,10 @@ public final class AnyPointer { public final T getAsStruct(FromStructReader factory) { return factory.fromStructReader(this.reader.getStruct()); } + + public final T getAsList(FromPointerReader factory) { + return factory.fromPointerReader(this.reader); + } } public static final class Builder {