diff --git a/compiler/src/main/cpp/capnpc-java.c++ b/compiler/src/main/cpp/capnpc-java.c++ index a109e58..ffeeeac 100644 --- a/compiler/src/main/cpp/capnpc-java.c++ +++ b/compiler/src/main/cpp/capnpc-java.c++ @@ -980,12 +980,21 @@ private: kj::String elementReaderType; kj::String elementBuilderType; + kj::String builderFactoryType; + kj::String readerFactoryType; + kj::String fieldSize; bool isStructOrCapList = false; + bool isStructList = false; if (kind == FieldKind::LIST) { bool primitiveElement = false; bool interface = false; switch (typeBody.getList().getElementType().which()) { case schema::Type::VOID: + primitiveElement = true; + builderFactoryType = kj::str("org.capnproto.PrimitiveElementFactory.VOID"); + readerFactoryType = kj::str(builderFactoryType); + fieldSize = kj::str("org.capnproto.FieldSize.VOID"); + break; case schema::Type::BOOL: case schema::Type::INT8: case schema::Type::INT16: @@ -1015,16 +1024,20 @@ private: break; case schema::Type::STRUCT: + isStructList = true; isStructOrCapList = true; primitiveElement = false; + elementReaderType = kj::str(typeName(typeBody.getList().getElementType()), ".Reader"); + elementBuilderType = kj::str(typeName(typeBody.getList().getElementType()), ".Builder"); + readerFactoryType = kj::str(elementReaderType, ".factory"), + builderFactoryType = kj::str(elementBuilderType, ".factory"), + fieldSize = kj::str(typeName(typeBody.getList().getElementType()),".STRUCT_SIZE.preferredListEncoding"); break; } - elementReaderType = kj::str( - typeName(typeBody.getList().getElementType()), - primitiveElement ? "" : interface ? "::Client" : ".Reader"); - elementBuilderType = kj::str( - typeName(typeBody.getList().getElementType()), - primitiveElement ? "" : interface ? "::Client" : ".Builder"); + if (primitiveElement) { + elementReaderType = kj::str(typeName(typeBody.getList().getElementType())); + elementBuilderType = kj::str(typeName(typeBody.getList().getElementType())); + } } @@ -1038,10 +1051,9 @@ private: spaces(indent), " public final ", type, ".Reader<", elementReaderType, ">", " get", titleCase, "() {\n", spaces(indent), " return new ", type, ".Reader<", elementReaderType, ">(\n", - spaces(indent), " ", elementReaderType, ".factory,\n", + spaces(indent), " ", readerFactoryType, ",\n", spaces(indent), " _reader.getPointerField(", offset, ").getList(", - // XXX what about lists of non-structs? - typeName(typeBody.getList().getElementType()),".STRUCT_SIZE.preferredListEncoding)", + fieldSize, ")", ");\n", spaces(indent), " }\n", "\n"), @@ -1061,10 +1073,11 @@ private: spaces(indent), " public final ", type, ".Builder<", elementBuilderType,">", " init", titleCase, "(int size) {\n", spaces(indent), " return new ", type, ".Builder<", elementBuilderType, ">(\n", - spaces(indent), " ", elementBuilderType,".factory,\n", - // XXX what about non-struct lists? - spaces(indent), " _builder.getPointerField(", offset, ").initStructList(", - "size,", typeName(typeBody.getList().getElementType()),".STRUCT_SIZE)", + spaces(indent), " ", builderFactoryType, ",\n", + spaces(indent), " _builder.getPointerField(", offset, ").init", + (isStructList ? + kj::strTree("StructList(size,", typeName(typeBody.getList().getElementType()),".STRUCT_SIZE)") : + kj::strTree("List(", fieldSize, ", size)")), ");\n", spaces(indent), " }\n"), diff --git a/compiler/src/test/schema/test.capnp b/compiler/src/test/schema/test.capnp index 0035a8a..81d6a3d 100644 --- a/compiler/src/test/schema/test.capnp +++ b/compiler/src/test/schema/test.capnp @@ -34,7 +34,7 @@ struct TestAllTypes { enumField @15 : TestEnum; interfaceField @16 : Void; # TODO -# voidList @17 : List(Void); + voidList @17 : List(Void); # boolList @18 : List(Bool); # ... } diff --git a/runtime/src/main/java/org/capnproto/PointerBuilder.java b/runtime/src/main/java/org/capnproto/PointerBuilder.java index d63671e..e5498fd 100644 --- a/runtime/src/main/java/org/capnproto/PointerBuilder.java +++ b/runtime/src/main/java/org/capnproto/PointerBuilder.java @@ -21,6 +21,10 @@ public final class PointerBuilder { return WireHelpers.initStructPointer(this.pointer, this.segment, size); } + public final ListBuilder initList(byte elementSize, int elementCount) { + throw new Error("unimplemented"); + } + public final ListBuilder initStructList(int elementCount, StructSize elementSize) { return WireHelpers.initStructListPointer(this.pointer, this.segment, elementCount, elementSize); } diff --git a/runtime/src/main/java/org/capnproto/PrimitiveElementFactory.java b/runtime/src/main/java/org/capnproto/PrimitiveElementFactory.java new file mode 100644 index 0000000..6a906ba --- /dev/null +++ b/runtime/src/main/java/org/capnproto/PrimitiveElementFactory.java @@ -0,0 +1,15 @@ +package org.capnproto; + +public interface PrimitiveElementFactory { + public T get(ListReader listReader, int index); + + public static final PrimitiveElementFactory VOID = new PrimitiveElementFactoryVoid(); +} + + +class PrimitiveElementFactoryVoid implements PrimitiveElementFactory { + public Void get(ListReader listReader, int index) { + return Void.VOID; + } +} + diff --git a/runtime/src/main/java/org/capnproto/PrimitiveList.java b/runtime/src/main/java/org/capnproto/PrimitiveList.java index f716ac4..dad5fc1 100644 --- a/runtime/src/main/java/org/capnproto/PrimitiveList.java +++ b/runtime/src/main/java/org/capnproto/PrimitiveList.java @@ -3,8 +3,10 @@ package org.capnproto; public class PrimitiveList { public static final class Reader { public final ListReader reader; + public final PrimitiveElementFactory factory; - public Reader(ListReader reader) { + public Reader(PrimitiveElementFactory factory, ListReader reader) { + this.factory = factory; this.reader = reader; } @@ -13,11 +15,19 @@ public class PrimitiveList { } public T get(int index) { - throw new Error(); + return this.factory.get(this.reader, index); } } public static final class Builder { + public final ListBuilder builder; + public final PrimitiveElementFactory factory; + + public Builder(PrimitiveElementFactory factory, ListBuilder builder) { + this.factory = factory; + this.builder = builder; + } + } }