Commit 4288dd27 authored by Kenton Varda's avatar Kenton Varda

Over the hump, new schema is working and passing most tests. Still lots of cleanup to do.

parent 0c7c610c
...@@ -5,33 +5,34 @@ ...@@ -5,33 +5,34 @@
namespace capnp { namespace capnp {
namespace schemas { namespace schemas {
static const ::capnp::_::AlignedData<18> b_b9c6f99ebf805f2c = { static const ::capnp::_::AlignedData<19> b_b9c6f99ebf805f2c = {
{ 0, 0, 0, 0, 3, 0, 4, 0, { 0, 0, 0, 0, 5, 0, 5, 0,
44, 95, 128, 191, 158, 249, 198, 185, 44, 95, 128, 191, 158, 249, 198, 185,
0, 0, 0, 0, 5, 0, 1, 0,
129, 78, 48, 184, 123, 125, 248, 189, 129, 78, 48, 184, 123, 125, 248, 189,
5, 0, 0, 0, 0, 0, 0, 0,
13, 0, 0, 0, 210, 0, 0, 0,
25, 0, 0, 0, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
20, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
17, 0, 0, 0, 210, 0, 0, 0,
29, 0, 0, 0, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
24, 0, 0, 0, 2, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0,
99, 97, 112, 110, 112, 47, 99, 43, 99, 97, 112, 110, 112, 47, 99, 43,
43, 46, 99, 97, 112, 110, 112, 58, 43, 46, 99, 97, 112, 110, 112, 58,
110, 97, 109, 101, 115, 112, 97, 99, 110, 97, 109, 101, 115, 112, 97, 99,
101, 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0,
1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 2, 0, 1, 0,
12, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, } 0, 0, 0, 0, 0, 0, 0, 0, }
}; };
static const ::capnp::_::RawSchema* const d_b9c6f99ebf805f2c[] = { static const ::capnp::_::RawSchema* const d_b9c6f99ebf805f2c[] = {
}; };
static const ::capnp::_::RawSchema::MemberInfo m_b9c6f99ebf805f2c[] = { static const uint16_t m_b9c6f99ebf805f2c[] = {};
}; static const uint16_t i_b9c6f99ebf805f2c[] = {};
const ::capnp::_::RawSchema s_b9c6f99ebf805f2c = { const ::capnp::_::RawSchema s_b9c6f99ebf805f2c = {
0xb9c6f99ebf805f2c, b_b9c6f99ebf805f2c.words, 18, d_b9c6f99ebf805f2c, m_b9c6f99ebf805f2c, 0xb9c6f99ebf805f2c, b_b9c6f99ebf805f2c.words, 19, d_b9c6f99ebf805f2c, m_b9c6f99ebf805f2c,
0, 0, nullptr, nullptr 0, 0, i_b9c6f99ebf805f2c, nullptr, nullptr
}; };
} // namespace schemas } // namespace schemas
namespace _ { // private namespace _ { // private
......
capnp bin capnp bin
capnpc-capnp bin
capnpc-c++ bin capnpc-c++ bin
...@@ -825,10 +825,21 @@ private: ...@@ -825,10 +825,21 @@ private:
enumerateDeps(proto, deps); enumerateDeps(proto, deps);
kj::Array<uint> membersByName; kj::Array<uint> membersByName;
kj::Array<uint> membersByDiscrim;
switch (proto.which()) { switch (proto.which()) {
case schema2::Node::STRUCT: case schema2::Node::STRUCT: {
membersByName = makeMembersByName(schema.asStruct().getFields()); auto structSchema = schema.asStruct();
membersByName = makeMembersByName(structSchema.getFields());
auto builder = kj::heapArrayBuilder<uint>(structSchema.getFields().size());
for (auto field: structSchema.getUnionFields()) {
builder.add(field.getIndex());
}
for (auto field: structSchema.getNonUnionFields()) {
builder.add(field.getIndex());
}
membersByDiscrim = builder.finish();
break; break;
}
case schema2::Node::ENUM: case schema2::Node::ENUM:
membersByName = makeMembersByName(schema.asEnum().getEnumerants()); membersByName = makeMembersByName(schema.asEnum().getEnumerants());
break; break;
...@@ -848,12 +859,15 @@ private: ...@@ -848,12 +859,15 @@ private:
return kj::strTree(" &s_", kj::hex(depId), ",\n"); return kj::strTree(" &s_", kj::hex(depId), ",\n");
}, },
"};\n" "};\n"
"static const ::capnp::_::RawSchema::MemberInfo m_", hexId, "[] = {\n", "static const uint16_t m_", hexId, "[] = {",
kj::StringTree(KJ_MAP(membersByName, index) { return kj::strTree(index); }, ", "), kj::StringTree(KJ_MAP(membersByName, index) { return kj::strTree(index); }, ", "),
"};\n" "};\n"
"static const uint16_t i_", hexId, "[] = {",
kj::StringTree(KJ_MAP(membersByDiscrim, index) { return kj::strTree(index); }, ", "),
"};\n"
"const ::capnp::_::RawSchema s_", hexId, " = {\n" "const ::capnp::_::RawSchema s_", hexId, " = {\n"
" 0x", hexId, ", b_", hexId, ".words, ", rawSchema.size(), ", d_", hexId, ", m_", hexId, ",\n" " 0x", hexId, ", b_", hexId, ".words, ", rawSchema.size(), ", d_", hexId, ", m_", hexId, ",\n"
" ", deps.size(), ", ", membersByName.size(), ", nullptr, nullptr\n" " ", deps.size(), ", ", membersByName.size(), ", i_", hexId, ", nullptr, nullptr\n"
"};\n"); "};\n");
switch (proto.which()) { switch (proto.which()) {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -1057,6 +1057,7 @@ private: ...@@ -1057,6 +1057,7 @@ private:
if (parent != nullptr) { if (parent != nullptr) {
uint64_t groupId = generateGroupId(parent->node.getId(), index); uint64_t groupId = generateGroupId(parent->node.getId(), index);
node.setId(groupId); node.setId(groupId);
node.setScopeId(parent->node.getId());
getSchema().setGroup(groupId); getSchema().setGroup(groupId);
} }
} }
...@@ -1201,10 +1202,9 @@ private: ...@@ -1201,10 +1202,9 @@ private:
.newOrphan<schema2::Node>(); .newOrphan<schema2::Node>();
auto node = orphan.get(); auto node = orphan.get();
// We'll set the ID later. // We'll set the ID and scope ID later.
node.setDisplayName(kj::str(parent.getDisplayName(), '.', name)); node.setDisplayName(kj::str(parent.getDisplayName(), '.', name));
node.setDisplayNamePrefixLength(node.getDisplayName().size() - name.size()); node.setDisplayNamePrefixLength(node.getDisplayName().size() - name.size());
node.setScopeId(parent.getId());
node.initStruct().setIsGroup(true); node.initStruct().setIsGroup(true);
// The remaining contents of node.struct will be filled in later. // The remaining contents of node.struct will be filled in later.
...@@ -1475,25 +1475,25 @@ private: ...@@ -1475,25 +1475,25 @@ private:
static kj::StringPtr getValueUnionFieldNameFor(schema2::Type::Which type) { static kj::StringPtr getValueUnionFieldNameFor(schema2::Type::Which type) {
switch (type) { switch (type) {
case schema2::Type::VOID: return "voidValue"; case schema2::Type::VOID: return "void";
case schema2::Type::BOOL: return "boolValue"; case schema2::Type::BOOL: return "bool";
case schema2::Type::INT8: return "int8Value"; case schema2::Type::INT8: return "int8";
case schema2::Type::INT16: return "int16Value"; case schema2::Type::INT16: return "int16";
case schema2::Type::INT32: return "int32Value"; case schema2::Type::INT32: return "int32";
case schema2::Type::INT64: return "int64Value"; case schema2::Type::INT64: return "int64";
case schema2::Type::UINT8: return "uint8Value"; case schema2::Type::UINT8: return "uint8";
case schema2::Type::UINT16: return "uint16Value"; case schema2::Type::UINT16: return "uint16";
case schema2::Type::UINT32: return "uint32Value"; case schema2::Type::UINT32: return "uint32";
case schema2::Type::UINT64: return "uint64Value"; case schema2::Type::UINT64: return "uint64";
case schema2::Type::FLOAT32: return "float32Value"; case schema2::Type::FLOAT32: return "float32";
case schema2::Type::FLOAT64: return "float64Value"; case schema2::Type::FLOAT64: return "float64";
case schema2::Type::TEXT: return "textValue"; case schema2::Type::TEXT: return "text";
case schema2::Type::DATA: return "dataValue"; case schema2::Type::DATA: return "data";
case schema2::Type::LIST: return "listValue"; case schema2::Type::LIST: return "list";
case schema2::Type::ENUM: return "enumValue"; case schema2::Type::ENUM: return "enum";
case schema2::Type::STRUCT: return "structValue"; case schema2::Type::STRUCT: return "struct";
case schema2::Type::INTERFACE: return "interfaceValue"; case schema2::Type::INTERFACE: return "interface";
case schema2::Type::OBJECT: return "objectValue"; case schema2::Type::OBJECT: return "object";
} }
KJ_FAIL_ASSERT("Unknown type."); KJ_FAIL_ASSERT("Unknown type.");
} }
...@@ -1533,35 +1533,38 @@ void NodeTranslator::compileValue(ValueExpression::Reader source, schema2::Type: ...@@ -1533,35 +1533,38 @@ void NodeTranslator::compileValue(ValueExpression::Reader source, schema2::Type:
break; break;
default: default:
#if 0
KJ_FAIL_ASSERT("Need to compile value type:", (uint)type.which(), KJ_FAIL_ASSERT("Need to compile value type:", (uint)type.which(),
wipNode.getReader().getDisplayName()); wipNode.getReader().getDisplayName());
} }
#else
break;
}
#if 0 auto valueUnion = toDynamic(target);
auto valueUnion = toDynamic(target).get("body").as<DynamicUnion>(); auto field = valueUnion.getSchema().getFieldByName(
auto member = valueUnion.getSchema().getMemberByName( getValueUnionFieldNameFor(type.which()));
getValueUnionFieldNameFor(type.getBody().which())); switch (type.which()) {
switch (type.getBody().which()) {
case schema2::Type::LIST: case schema2::Type::LIST:
KJ_IF_MAYBE(listSchema, makeListSchemaOf(type.getBody().getListType())) { KJ_IF_MAYBE(listSchema, makeListSchemaOf(type.getList())) {
DynamicSlot slot(valueUnion, member, *listSchema); DynamicSlot slot(valueUnion, field, *listSchema);
compileValue(source, slot, isBootstrap); compileValue(source, slot, isBootstrap);
} }
break; break;
case schema2::Type::STRUCT: case schema2::Type::STRUCT:
KJ_IF_MAYBE(structSchema, resolver.resolveBootstrapSchema(type.getBody().getStructType())) { KJ_IF_MAYBE(structSchema, resolver.resolveBootstrapSchema(type.getStruct())) {
DynamicSlot slot(valueUnion, member, structSchema->asStruct()); DynamicSlot slot(valueUnion, field, structSchema->asStruct());
compileValue(source, slot, isBootstrap); compileValue(source, slot, isBootstrap);
} }
break; break;
case schema2::Type::ENUM: case schema2::Type::ENUM:
KJ_IF_MAYBE(enumSchema, resolver.resolveBootstrapSchema(type.getBody().getEnumType())) { KJ_IF_MAYBE(enumSchema, resolver.resolveBootstrapSchema(type.getEnum())) {
DynamicSlot slot(valueUnion, member, enumSchema->asEnum()); DynamicSlot slot(valueUnion, field, enumSchema->asEnum());
compileValue(source, slot, isBootstrap); compileValue(source, slot, isBootstrap);
} }
break; break;
default: default:
DynamicSlot slot(valueUnion, member); DynamicSlot slot(valueUnion, field);
compileValue(source, slot, isBootstrap); compileValue(source, slot, isBootstrap);
break; break;
} }
......
...@@ -246,24 +246,24 @@ TEST(DynamicApi, UnionsRead) { ...@@ -246,24 +246,24 @@ TEST(DynamicApi, UnionsRead) {
{ {
auto dynamic = toDynamic(root.asReader()); auto dynamic = toDynamic(root.asReader());
{ {
auto u = dynamic.get("union0").as<DynamicUnion>(); auto u = dynamic.get("union0").as<DynamicStruct>();
EXPECT_MAYBE_EQ(w, u.which(), "u0f1s32", w->getProto().getName()); EXPECT_MAYBE_EQ(w, u.which(), "u0f1s32", w->getProto().getName());
EXPECT_EQ(1234567, u.get().as<int32_t>()); EXPECT_EQ(1234567, u.get("u0f1s32").as<int32_t>());
} }
{ {
auto u = dynamic.get("union1").as<DynamicUnion>(); auto u = dynamic.get("union1").as<DynamicStruct>();
EXPECT_MAYBE_EQ(w, u.which(), "u1f1sp", w->getProto().getName()); EXPECT_MAYBE_EQ(w, u.which(), "u1f1sp", w->getProto().getName());
EXPECT_EQ("foo", u.get().as<Text>()); EXPECT_EQ("foo", u.get("u1f1sp").as<Text>());
} }
{ {
auto u = dynamic.get("union2").as<DynamicUnion>(); auto u = dynamic.get("union2").as<DynamicStruct>();
EXPECT_MAYBE_EQ(w, u.which(), "u2f0s1", w->getProto().getName()); EXPECT_MAYBE_EQ(w, u.which(), "u2f0s1", w->getProto().getName());
EXPECT_TRUE(u.get().as<bool>()); EXPECT_TRUE(u.get("u2f0s1").as<bool>());
} }
{ {
auto u = dynamic.get("union3").as<DynamicUnion>(); auto u = dynamic.get("union3").as<DynamicStruct>();
EXPECT_MAYBE_EQ(w, u.which(), "u3f0s64", w->getProto().getName()); EXPECT_MAYBE_EQ(w, u.which(), "u3f0s64", w->getProto().getName());
EXPECT_EQ(1234567890123456789ll, u.get().as<int64_t>()); EXPECT_EQ(1234567890123456789ll, u.get("u3f0s64").as<int64_t>());
} }
} }
...@@ -271,24 +271,24 @@ TEST(DynamicApi, UnionsRead) { ...@@ -271,24 +271,24 @@ TEST(DynamicApi, UnionsRead) {
// Again as a builder. // Again as a builder.
auto dynamic = toDynamic(root); auto dynamic = toDynamic(root);
{ {
auto u = dynamic.get("union0").as<DynamicUnion>(); auto u = dynamic.get("union0").as<DynamicStruct>();
EXPECT_MAYBE_EQ(w, u.which(), "u0f1s32", w->getProto().getName()); EXPECT_MAYBE_EQ(w, u.which(), "u0f1s32", w->getProto().getName());
EXPECT_EQ(1234567, u.get().as<int32_t>()); EXPECT_EQ(1234567, u.get("u0f1s32").as<int32_t>());
} }
{ {
auto u = dynamic.get("union1").as<DynamicUnion>(); auto u = dynamic.get("union1").as<DynamicStruct>();
EXPECT_MAYBE_EQ(w, u.which(), "u1f1sp", w->getProto().getName()); EXPECT_MAYBE_EQ(w, u.which(), "u1f1sp", w->getProto().getName());
EXPECT_EQ("foo", u.get().as<Text>()); EXPECT_EQ("foo", u.get("u1f1sp").as<Text>());
} }
{ {
auto u = dynamic.get("union2").as<DynamicUnion>(); auto u = dynamic.get("union2").as<DynamicStruct>();
EXPECT_MAYBE_EQ(w, u.which(), "u2f0s1", w->getProto().getName()); EXPECT_MAYBE_EQ(w, u.which(), "u2f0s1", w->getProto().getName());
EXPECT_TRUE(u.get().as<bool>()); EXPECT_TRUE(u.get("u2f0s1").as<bool>());
} }
{ {
auto u = dynamic.get("union3").as<DynamicUnion>(); auto u = dynamic.get("union3").as<DynamicStruct>();
EXPECT_MAYBE_EQ(w, u.which(), "u3f0s64", w->getProto().getName()); EXPECT_MAYBE_EQ(w, u.which(), "u3f0s64", w->getProto().getName());
EXPECT_EQ(1234567890123456789ll, u.get().as<int64_t>()); EXPECT_EQ(1234567890123456789ll, u.get("u3f0s64").as<int64_t>());
} }
} }
} }
...@@ -305,10 +305,10 @@ TEST(DynamicApi, UnionsWrite) { ...@@ -305,10 +305,10 @@ TEST(DynamicApi, UnionsWrite) {
MallocMessageBuilder builder; MallocMessageBuilder builder;
auto root = builder.initRoot<DynamicStruct>(Schema::from<TestUnion>()); auto root = builder.initRoot<DynamicStruct>(Schema::from<TestUnion>());
root.get("union0").as<DynamicUnion>().set("u0f1s32", 1234567); root.get("union0").as<DynamicStruct>().set("u0f1s32", 1234567);
root.get("union1").as<DynamicUnion>().set("u1f1sp", "foo"); root.get("union1").as<DynamicStruct>().set("u1f1sp", "foo");
root.get("union2").as<DynamicUnion>().set("u2f0s1", true); root.get("union2").as<DynamicStruct>().set("u2f0s1", true);
root.get("union3").as<DynamicUnion>().set("u3f0s64", 1234567890123456789ll); root.get("union3").as<DynamicStruct>().set("u3f0s64", 1234567890123456789ll);
auto reader = root.asReader().as<TestUnion>(); auto reader = root.asReader().as<TestUnion>();
ASSERT_EQ(TestUnion::Union0::U0F1S32, reader.getUnion0().which()); ASSERT_EQ(TestUnion::Union0::U0F1S32, reader.getUnion0().which());
...@@ -326,13 +326,6 @@ TEST(DynamicApi, UnionsWrite) { ...@@ -326,13 +326,6 @@ TEST(DynamicApi, UnionsWrite) {
// Can't access union members by name from the root. // Can't access union members by name from the root.
EXPECT_ANY_THROW(root.get("u0f1s32")); EXPECT_ANY_THROW(root.get("u0f1s32"));
EXPECT_ANY_THROW(root.set("u0f1s32", 1234567)); EXPECT_ANY_THROW(root.set("u0f1s32", 1234567));
// But can access them by member pointer.
auto member = root.get("union0").as<DynamicUnion>().getSchema().getMemberByName("u0f1s32");
EXPECT_EQ(1234567, root.get(member).as<int>());
auto member2 = root.get("union0").as<DynamicUnion>().getSchema().getMemberByName("u0f1sp");
root.set(member2, "foo");
EXPECT_EQ("foo", reader.getUnion0().getU0f1sp());
} }
TEST(DynamicApi, UnnamedUnion) { TEST(DynamicApi, UnnamedUnion) {
...@@ -340,44 +333,33 @@ TEST(DynamicApi, UnnamedUnion) { ...@@ -340,44 +333,33 @@ TEST(DynamicApi, UnnamedUnion) {
StructSchema schema = Schema::from<test::TestUnnamedUnion>(); StructSchema schema = Schema::from<test::TestUnnamedUnion>();
auto root = builder.initRoot<DynamicStruct>(schema); auto root = builder.initRoot<DynamicStruct>(schema);
DynamicUnion::Builder unionBuilder = EXPECT_EQ(schema.getFieldByName("foo"), KJ_ASSERT_NONNULL(root.which()));
root.get(KJ_ASSERT_NONNULL(schema.getUnnamedUnion())).as<DynamicUnion>();
EXPECT_EQ(schema.getMemberByName("foo"), KJ_ASSERT_NONNULL(unionBuilder.which()));
root.set("bar", 321); root.set("bar", 321);
EXPECT_EQ(schema.getMemberByName("bar"), KJ_ASSERT_NONNULL(unionBuilder.which())); EXPECT_EQ(schema.getFieldByName("bar"), KJ_ASSERT_NONNULL(root.which()));
EXPECT_EQ(321u, root.get("bar").as<uint>()); EXPECT_EQ(321u, root.get("bar").as<uint>());
EXPECT_EQ(321u, root.asReader().get("bar").as<uint>()); EXPECT_EQ(321u, root.asReader().get("bar").as<uint>());
EXPECT_EQ(321u, unionBuilder.get().as<uint>());
EXPECT_EQ(321u, unionBuilder.asReader().get().as<uint>());
EXPECT_ANY_THROW(root.get("foo")); EXPECT_ANY_THROW(root.get("foo"));
EXPECT_ANY_THROW(root.asReader().get("foo")); EXPECT_ANY_THROW(root.asReader().get("foo"));
root.set("foo", 123); root.set("foo", 123);
EXPECT_EQ(schema.getMemberByName("foo"), KJ_ASSERT_NONNULL(unionBuilder.which())); EXPECT_EQ(schema.getFieldByName("foo"), KJ_ASSERT_NONNULL(root.which()));
EXPECT_EQ(123u, root.get("foo").as<uint>()); EXPECT_EQ(123u, root.get("foo").as<uint>());
EXPECT_EQ(123u, root.asReader().get("foo").as<uint>()); EXPECT_EQ(123u, root.asReader().get("foo").as<uint>());
EXPECT_EQ(123u, unionBuilder.get().as<uint>());
EXPECT_EQ(123u, unionBuilder.asReader().get().as<uint>());
EXPECT_ANY_THROW(root.get("bar")); EXPECT_ANY_THROW(root.get("bar"));
EXPECT_ANY_THROW(root.asReader().get("bar")); EXPECT_ANY_THROW(root.asReader().get("bar"));
unionBuilder.set("bar", 321); root.set("bar", 321);
EXPECT_EQ(schema.getMemberByName("bar"), KJ_ASSERT_NONNULL(unionBuilder.which())); EXPECT_EQ(schema.getFieldByName("bar"), KJ_ASSERT_NONNULL(root.which()));
EXPECT_EQ(321u, root.get("bar").as<uint>()); EXPECT_EQ(321u, root.get("bar").as<uint>());
EXPECT_EQ(321u, root.asReader().get("bar").as<uint>()); EXPECT_EQ(321u, root.asReader().get("bar").as<uint>());
EXPECT_EQ(321u, unionBuilder.get().as<uint>());
EXPECT_EQ(321u, unionBuilder.asReader().get().as<uint>());
EXPECT_ANY_THROW(root.get("foo")); EXPECT_ANY_THROW(root.get("foo"));
EXPECT_ANY_THROW(root.asReader().get("foo")); EXPECT_ANY_THROW(root.asReader().get("foo"));
unionBuilder.set("foo", 123); root.set("foo", 123);
EXPECT_EQ(schema.getMemberByName("foo"), KJ_ASSERT_NONNULL(unionBuilder.which())); EXPECT_EQ(schema.getFieldByName("foo"), KJ_ASSERT_NONNULL(root.which()));
EXPECT_EQ(123u, root.get("foo").as<uint>()); EXPECT_EQ(123u, root.get("foo").as<uint>());
EXPECT_EQ(123u, root.asReader().get("foo").as<uint>()); EXPECT_EQ(123u, root.asReader().get("foo").as<uint>());
EXPECT_EQ(123u, unionBuilder.get().as<uint>());
EXPECT_EQ(123u, unionBuilder.asReader().get().as<uint>());
EXPECT_ANY_THROW(root.get("bar")); EXPECT_ANY_THROW(root.get("bar"));
EXPECT_ANY_THROW(root.asReader().get("bar")); EXPECT_ANY_THROW(root.asReader().get("bar"));
} }
...@@ -403,7 +385,7 @@ TEST(DynamicApi, LateUnion) { ...@@ -403,7 +385,7 @@ TEST(DynamicApi, LateUnion) {
MallocMessageBuilder builder; MallocMessageBuilder builder;
auto root = builder.initRoot<DynamicStruct>(Schema::from<test::TestLateUnion>()); auto root = builder.initRoot<DynamicStruct>(Schema::from<test::TestLateUnion>());
root.get("theUnion").as<DynamicUnion>().set("qux", "hello"); root.get("theUnion").as<DynamicStruct>().set("qux", "hello");
EXPECT_EQ("hello", root.as<test::TestLateUnion>().getTheUnion().getQux()); EXPECT_EQ("hello", root.as<test::TestLateUnion>().getTheUnion().getQux());
} }
......
...@@ -719,7 +719,7 @@ void DynamicStruct::Builder::clear(StructSchema::Field field) { ...@@ -719,7 +719,7 @@ void DynamicStruct::Builder::clear(StructSchema::Field field) {
case schema2::Type::STRUCT: case schema2::Type::STRUCT:
case schema2::Type::OBJECT: case schema2::Type::OBJECT:
builder.disown(regularField.getOffset() * POINTERS); builder.disown(regularField.getOffset() * POINTERS);
break; return;
case schema2::Type::INTERFACE: case schema2::Type::INTERFACE:
KJ_FAIL_ASSERT("Interfaces not yet implemented."); KJ_FAIL_ASSERT("Interfaces not yet implemented.");
...@@ -737,7 +737,7 @@ void DynamicStruct::Builder::clear(StructSchema::Field field) { ...@@ -737,7 +737,7 @@ void DynamicStruct::Builder::clear(StructSchema::Field field) {
for (auto subField: group.schema.getNonUnionFields()) { for (auto subField: group.schema.getNonUnionFields()) {
group.clear(subField); group.clear(subField);
} }
break; return;
} }
} }
......
...@@ -389,17 +389,11 @@ TEST(Encoding, UnnamedUnion) { ...@@ -389,17 +389,11 @@ TEST(Encoding, UnnamedUnion) {
EXPECT_DEBUG_ANY_THROW(root.asReader().getBar()); EXPECT_DEBUG_ANY_THROW(root.asReader().getBar());
StructSchema schema = Schema::from<test::TestUnnamedUnion>(); StructSchema schema = Schema::from<test::TestUnnamedUnion>();
KJ_IF_MAYBE(u, schema.getUnnamedUnion()) {
// The discriminant is allocated just before allocating "bar".
EXPECT_EQ(2, u->getProto().getBody().getUnionMember().getDiscriminantOffset());
EXPECT_EQ(0, u->getMemberByName("foo").getProto().getBody().getFieldMember().getOffset());
EXPECT_EQ(2, u->getMemberByName("bar").getProto().getBody().getFieldMember().getOffset());
// The union receives the ordinal of its first member, since it does not explicitly declare one. // The discriminant is allocated just before allocating "bar".
EXPECT_EQ(1, u->getProto().getOrdinal()); EXPECT_EQ(2, schema.getProto().getStruct().getDiscriminantOffset());
} else { EXPECT_EQ(0, schema.getFieldByName("foo").getProto().getRegular().getOffset());
ADD_FAILURE() << "getUnnamedUnion() should have returned non-null."; EXPECT_EQ(2, schema.getFieldByName("bar").getProto().getRegular().getOffset());
}
} }
TEST(Encoding, Groups) { TEST(Encoding, Groups) {
......
...@@ -163,16 +163,7 @@ struct RawSchema { ...@@ -163,16 +163,7 @@ struct RawSchema {
// //
// TODO(someday): Make this a hashtable. // TODO(someday): Make this a hashtable.
struct MemberInfo { const uint16_t* membersByName;
uint16_t value;
inline operator uint16_t() const { return value; }
MemberInfo() = default;
constexpr MemberInfo(uint16_t value): value(value) {}
constexpr MemberInfo(uint16_t value, uint16_t dummy): value(value) {}
};
const MemberInfo* membersByName;
// Indexes of members sorted by name. Used to implement name lookup. // Indexes of members sorted by name. Used to implement name lookup.
// TODO(someday): Make this a hashtable. // TODO(someday): Make this a hashtable.
...@@ -229,7 +220,6 @@ template <typename T> ...@@ -229,7 +220,6 @@ template <typename T>
using UnionParentType = typename UnionParentType_<T>::Type; using UnionParentType = typename UnionParentType_<T>::Type;
kj::StringTree structString(StructReader reader, const RawSchema& schema); kj::StringTree structString(StructReader reader, const RawSchema& schema);
kj::StringTree unionString(StructReader reader, const RawSchema& schema, uint memberIndex);
// Declared here so that we can declare inline stringify methods on generated types. // Declared here so that we can declare inline stringify methods on generated types.
// Defined in stringify.c++, which depends on dynamic.c++, which is allowed not to be linked in. // Defined in stringify.c++, which depends on dynamic.c++, which is allowed not to be linked in.
...@@ -238,12 +228,6 @@ inline kj::StringTree structString(StructReader reader) { ...@@ -238,12 +228,6 @@ inline kj::StringTree structString(StructReader reader) {
return structString(reader, rawSchema<T>()); return structString(reader, rawSchema<T>());
} }
template <typename T>
inline kj::StringTree unionString(StructReader reader) {
#warning "remove this"
return kj::strTree();
}
} // namespace _ (private) } // namespace _ (private)
template <typename T> template <typename T>
......
...@@ -53,7 +53,7 @@ TEST(SchemaLoader, Load) { ...@@ -53,7 +53,7 @@ TEST(SchemaLoader, Load) {
EXPECT_TRUE(testListsSchema.getDependency(typeId<test::TestLists::StructP>()) == structPSchema); EXPECT_TRUE(testListsSchema.getDependency(typeId<test::TestLists::StructP>()) == structPSchema);
auto struct16Schema = testListsSchema.getDependency(typeId<test::TestLists::Struct16>()); auto struct16Schema = testListsSchema.getDependency(typeId<test::TestLists::Struct16>());
EXPECT_EQ(0u, struct16Schema.getProto().getBody().getStructNode().getMembers().size()); EXPECT_EQ(0u, struct16Schema.getProto().getStruct().getFields().size());
} }
TEST(SchemaLoader, LoadLateUnion) { TEST(SchemaLoader, LoadLateUnion) {
...@@ -61,13 +61,15 @@ TEST(SchemaLoader, LoadLateUnion) { ...@@ -61,13 +61,15 @@ TEST(SchemaLoader, LoadLateUnion) {
StructSchema schema = StructSchema schema =
loader.load(Schema::from<test::TestLateUnion>().getProto()).asStruct(); loader.load(Schema::from<test::TestLateUnion>().getProto()).asStruct();
loader.load(Schema::from<test::TestLateUnion::TheUnion>().getProto()).asStruct();
EXPECT_EQ(6, schema.getMemberByName("theUnion").asUnion() loader.load(Schema::from<test::TestLateUnion::AnotherUnion>().getProto()).asStruct();
.getMemberByName("grault").getProto().getOrdinal());
EXPECT_EQ(9, schema.getMemberByName("anotherUnion").asUnion() EXPECT_EQ(6, schema.getDependency(schema.getFieldByName("theUnion").getProto().getGroup())
.getMemberByName("corge").getProto().getOrdinal()); .asStruct().getFieldByName("grault").getProto().getOrdinal().getExplicit());
EXPECT_TRUE(schema.findMemberByName("corge") == nullptr); EXPECT_EQ(9, schema.getDependency(schema.getFieldByName("anotherUnion").getProto().getGroup())
EXPECT_TRUE(schema.findMemberByName("grault") == nullptr); .asStruct().getFieldByName("corge").getProto().getOrdinal().getExplicit());
EXPECT_TRUE(schema.findFieldByName("corge") == nullptr);
EXPECT_TRUE(schema.findFieldByName("grault") == nullptr);
} }
TEST(SchemaLoader, LoadUnnamedUnion) { TEST(SchemaLoader, LoadUnnamedUnion) {
...@@ -76,18 +78,12 @@ TEST(SchemaLoader, LoadUnnamedUnion) { ...@@ -76,18 +78,12 @@ TEST(SchemaLoader, LoadUnnamedUnion) {
StructSchema schema = StructSchema schema =
loader.load(Schema::from<test::TestUnnamedUnion>().getProto()).asStruct(); loader.load(Schema::from<test::TestUnnamedUnion>().getProto()).asStruct();
EXPECT_TRUE(schema.findMemberByName("") == nullptr); EXPECT_TRUE(schema.findFieldByName("") == nullptr);
KJ_IF_MAYBE(u, schema.getUnnamedUnion()) { EXPECT_TRUE(schema.findFieldByName("foo") != nullptr);
EXPECT_TRUE(schema.getMemberByName("foo") == u->getMemberByName("foo")); EXPECT_TRUE(schema.findFieldByName("bar") != nullptr);
EXPECT_TRUE(schema.getMemberByName("bar") == u->getMemberByName("bar")); EXPECT_TRUE(schema.findFieldByName("before") != nullptr);
EXPECT_TRUE(u->findMemberByName("before") == nullptr); EXPECT_TRUE(schema.findFieldByName("after") != nullptr);
EXPECT_TRUE(u->findMemberByName("after") == nullptr);
EXPECT_TRUE(schema.findMemberByName("before") != nullptr);
EXPECT_TRUE(schema.findMemberByName("after") != nullptr);
} else {
ADD_FAILURE() << "getUnnamedUnion() should have returned non-null.";
}
} }
#if KJ_NO_EXCEPTIONS #if KJ_NO_EXCEPTIONS
...@@ -161,12 +157,14 @@ TEST(SchemaLoader, Use) { ...@@ -161,12 +157,14 @@ TEST(SchemaLoader, Use) {
// Finally, let's test some unions. // Finally, let's test some unions.
StructSchema unionSchema = loader.load(Schema::from<TestUnion>().getProto()).asStruct(); StructSchema unionSchema = loader.load(Schema::from<TestUnion>().getProto()).asStruct();
loader.load(Schema::from<TestUnion::Union0>().getProto());
loader.load(Schema::from<TestUnion::Union1>().getProto());
{ {
MallocMessageBuilder builder; MallocMessageBuilder builder;
auto root = builder.getRoot<DynamicStruct>(unionSchema); auto root = builder.getRoot<DynamicStruct>(unionSchema);
root.get("union0").as<DynamicUnion>().set("u0f1s16", 123); root.get("union0").as<DynamicStruct>().set("u0f1s16", 123);
root.get("union1").as<DynamicUnion>().set("u1f0sp", "hello"); root.get("union1").as<DynamicStruct>().set("u1f0sp", "hello");
auto reader = builder.getRoot<TestUnion>().asReader(); auto reader = builder.getRoot<TestUnion>().asReader();
EXPECT_EQ(123, reader.getUnion0().getU0f1s16()); EXPECT_EQ(123, reader.getUnion0().getU0f1s16());
...@@ -178,18 +176,18 @@ template <typename T> ...@@ -178,18 +176,18 @@ template <typename T>
Schema loadUnderAlternateTypeId(SchemaLoader& loader, uint64_t id) { Schema loadUnderAlternateTypeId(SchemaLoader& loader, uint64_t id) {
MallocMessageBuilder schemaBuilder; MallocMessageBuilder schemaBuilder;
schemaBuilder.setRoot(Schema::from<T>().getProto()); schemaBuilder.setRoot(Schema::from<T>().getProto());
auto root = schemaBuilder.getRoot<schema::Node>(); auto root = schemaBuilder.getRoot<schema2::Node>();
root.setId(id); root.setId(id);
if (root.getBody().which() == schema::Node::Body::STRUCT_NODE) { if (root.which() == schema2::Node::STRUCT) {
// If the struct contains any self-referential members, change their type IDs as well. // If the struct contains any self-referential members, change their type IDs as well.
auto members = root.getBody().getStructNode().getMembers(); auto fields = root.getStruct().getFields();
for (auto member: members) { for (auto field: fields) {
if (member.getBody().which() == schema::StructNode::Member::Body::FIELD_MEMBER) { if (field.which() == schema2::Field::REGULAR) {
auto type = member.getBody().getFieldMember().getType().getBody(); auto type = field.getRegular().getType();
if (type.which() == schema::Type::Body::STRUCT_TYPE && if (type.which() == schema2::Type::STRUCT &&
type.getStructType() == typeId<T>()) { type.getStruct() == typeId<T>()) {
type.setStructType(id); type.setStruct(id);
} }
} }
} }
...@@ -284,7 +282,7 @@ TEST(SchemaLoader, EnumerateNoPlaceholders) { ...@@ -284,7 +282,7 @@ TEST(SchemaLoader, EnumerateNoPlaceholders) {
class FakeLoaderCallback: public SchemaLoader::LazyLoadCallback { class FakeLoaderCallback: public SchemaLoader::LazyLoadCallback {
public: public:
FakeLoaderCallback(const schema::Node::Reader node): node(node), loaded(false) {} FakeLoaderCallback(const schema2::Node::Reader node): node(node), loaded(false) {}
bool isLoaded() { return loaded; } bool isLoaded() { return loaded; }
...@@ -301,7 +299,7 @@ public: ...@@ -301,7 +299,7 @@ public:
} }
private: private:
const schema::Node::Reader node; const schema2::Node::Reader node;
mutable bool loaded = false; mutable bool loaded = false;
}; };
......
...@@ -170,10 +170,9 @@ public: ...@@ -170,10 +170,9 @@ public:
return result.begin(); return result.begin();
} }
const _::RawSchema::MemberInfo* makeMemberInfoArray(uint32_t* count) { const uint16_t* makeMemberInfoArray(uint32_t* count) {
*count = members.size(); *count = members.size();
kj::ArrayPtr<_::RawSchema::MemberInfo> result = kj::ArrayPtr<uint16_t> result = loader.arena.allocateArray<uint16_t>(*count);
loader.arena.allocateArray<_::RawSchema::MemberInfo>(*count);
uint pos = 0; uint pos = 0;
for (auto& member: members) { for (auto& member: members) {
result[pos++] = member.second; result[pos++] = member.second;
......
...@@ -52,6 +52,12 @@ private: ...@@ -52,6 +52,12 @@ private:
std::map<kj::StringPtr, kj::StringPtr> files; std::map<kj::StringPtr, kj::StringPtr> files;
}; };
static uint64_t getFieldTypeFileId(StructSchema::Field field) {
return field.getContainingStruct()
.getDependency(field.getProto().getRegular().getType().getStruct())
.getProto().getScopeId();
}
TEST(SchemaParser, Basic) { TEST(SchemaParser, Basic) {
SchemaParser parser; SchemaParser parser;
FakeFileReader reader; FakeFileReader reader;
...@@ -90,24 +96,18 @@ TEST(SchemaParser, Basic) { ...@@ -90,24 +96,18 @@ TEST(SchemaParser, Basic) {
auto barProto = barSchema.getProto(); auto barProto = barSchema.getProto();
EXPECT_EQ(0x8123456789abcdefull, barProto.getId()); EXPECT_EQ(0x8123456789abcdefull, barProto.getId());
EXPECT_EQ("foo2/bar2.capnp", barProto.getDisplayName()); EXPECT_EQ("foo2/bar2.capnp", barProto.getDisplayName());
auto barImports = barProto.getBody().getFileNode().getImports();
ASSERT_EQ(4, barImports.size());
EXPECT_EQ("../qux/corge.capnp", barImports[0].getName());
EXPECT_EQ(0x83456789abcdef12ull, barImports[0].getId());
EXPECT_EQ("/garply.capnp", barImports[1].getName());
EXPECT_EQ(0x856789abcdef1234ull, barImports[1].getId());
EXPECT_EQ("/grault.capnp", barImports[2].getName());
EXPECT_EQ(0x8456789abcdef123ull, barImports[2].getId());
EXPECT_EQ("baz.capnp", barImports[3].getName());
EXPECT_EQ(0x823456789abcdef1ull, barImports[3].getId());
auto barStruct = barSchema.getNested("Bar"); auto barStruct = barSchema.getNested("Bar");
auto barMembers = barStruct.asStruct().getMembers(); auto barFields = barStruct.asStruct().getFields();
ASSERT_EQ(4, barMembers.size()); ASSERT_EQ(4, barFields.size());
EXPECT_EQ("baz", barMembers[0].getProto().getName()); EXPECT_EQ("baz", barFields[0].getProto().getName());
EXPECT_EQ("corge", barMembers[1].getProto().getName()); EXPECT_EQ(0x823456789abcdef1ull, getFieldTypeFileId(barFields[0]));
EXPECT_EQ("grault", barMembers[2].getProto().getName()); EXPECT_EQ("corge", barFields[1].getProto().getName());
EXPECT_EQ("garply", barMembers[3].getProto().getName()); EXPECT_EQ(0x83456789abcdef12ull, getFieldTypeFileId(barFields[1]));
EXPECT_EQ("grault", barFields[2].getProto().getName());
EXPECT_EQ(0x8456789abcdef123ull, getFieldTypeFileId(barFields[2]));
EXPECT_EQ("garply", barFields[3].getProto().getName());
EXPECT_EQ(0x856789abcdef1234ull, getFieldTypeFileId(barFields[3]));
auto bazSchema = parser.parseFile(SchemaFile::newDiskFile( auto bazSchema = parser.parseFile(SchemaFile::newDiskFile(
kj::str("not/used/because/already/loaded"), kj::str("not/used/because/already/loaded"),
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -65,8 +65,21 @@ public: ...@@ -65,8 +65,21 @@ public:
Schema getDependency(uint64_t id) const; Schema getDependency(uint64_t id) const;
// Gets the Schema for one of this Schema's dependencies. For example, if this Schema is for a // Gets the Schema for one of this Schema's dependencies. For example, if this Schema is for a
// struct, you could look up the schema for one of its fields' types. Throws an exception if this // struct, you could look up the schema for one of its fields' types. Throws an exception if this
// schema doesn't actually depend on the given id. Note that annotation declarations are not // schema doesn't actually depend on the given id.
// considered dependencies for this purpose. //
// Note that not all type IDs found in the schema node are considered "dependencies" -- only the
// ones that are needed to implement the dynamic API are. That includes:
// - Field types.
// - Group types.
// - scopeId for group nodes, but NOT otherwise.
// - Method parameter and return types.
//
// The following are NOT considered dependencies:
// - Nested nodes.
// - scopeId for a non-group node.
// - Annotations.
//
// To obtain schemas for those, you would need a SchemaLoader.
StructSchema asStruct() const; StructSchema asStruct() const;
EnumSchema asEnum() const; EnumSchema asEnum() const;
......
This diff is collapsed.
This diff is collapsed.
...@@ -318,21 +318,23 @@ TEST(Stringify, PrettyPrintAdvanced) { ...@@ -318,21 +318,23 @@ TEST(Stringify, PrettyPrintAdvanced) {
auto s = root.getUn().initAllTypes(); auto s = root.getUn().initAllTypes();
EXPECT_EQ( EXPECT_EQ(
"(un = allTypes())", "(un = (allTypes = ()))",
prettyPrint(root).flatten()); prettyPrint(root).flatten());
s.setInt32Field(123); s.setInt32Field(123);
EXPECT_EQ( EXPECT_EQ(
"( un = allTypes(int32Field = 123) )", "( un = (\n"
" allTypes = (int32Field = 123) ) )",
prettyPrint(root).flatten()); prettyPrint(root).flatten());
s.setTextField("foo"); s.setTextField("foo");
s.setUInt64Field(0xffffffffffffffffull); s.setUInt64Field(0xffffffffffffffffull);
EXPECT_EQ( EXPECT_EQ(
"( un = allTypes(\n" "( un = (\n"
" allTypes = (\n"
" int32Field = 123,\n" " int32Field = 123,\n"
" uInt64Field = 18446744073709551615,\n" " uInt64Field = 18446744073709551615,\n"
" textField = \"foo\" ) )", " textField = \"foo\" ) ) )",
prettyPrint(root).flatten()); prettyPrint(root).flatten());
} }
} }
...@@ -347,16 +349,16 @@ TEST(Stringify, Unions) { ...@@ -347,16 +349,16 @@ TEST(Stringify, Unions) {
root.getUnion3().setU3f0s64(123456789012345678ll); root.getUnion3().setU3f0s64(123456789012345678ll);
EXPECT_EQ("(" EXPECT_EQ("("
"union0 = u0f0s16(321), " "union0 = (u0f0s16 = 321), "
"union1 = u1f0sp(\"foo\"), " "union1 = (u1f0sp = \"foo\"), "
"union2 = u2f0s1(true), " "union2 = (u2f0s1 = true), "
"union3 = u3f0s64(123456789012345678))", "union3 = (u3f0s64 = 123456789012345678))",
kj::str(root)); kj::str(root));
EXPECT_EQ("u0f0s16(321)", kj::str(root.getUnion0())); EXPECT_EQ("(u0f0s16 = 321)", kj::str(root.getUnion0()));
EXPECT_EQ("u1f0sp(\"foo\")", kj::str(root.getUnion1())); EXPECT_EQ("(u1f0sp = \"foo\")", kj::str(root.getUnion1()));
EXPECT_EQ("u2f0s1(true)", kj::str(root.getUnion2())); EXPECT_EQ("(u2f0s1 = true)", kj::str(root.getUnion2()));
EXPECT_EQ("u3f0s64(123456789012345678)", kj::str(root.getUnion3())); EXPECT_EQ("(u3f0s64 = 123456789012345678)", kj::str(root.getUnion3()));
} }
TEST(Stringify, UnnamedUnions) { TEST(Stringify, UnnamedUnions) {
...@@ -365,24 +367,24 @@ TEST(Stringify, UnnamedUnions) { ...@@ -365,24 +367,24 @@ TEST(Stringify, UnnamedUnions) {
root.setBar(123); root.setBar(123);
EXPECT_EQ("(bar(123))", kj::str(root)); EXPECT_EQ("(bar = 123)", kj::str(root));
EXPECT_EQ("(bar(123))", prettyPrint(root).flatten()); EXPECT_EQ("(bar = 123)", prettyPrint(root).flatten());
root.setAfter("foooooooooooooooooooooooooooooooo"); root.setAfter("foooooooooooooooooooooooooooooooo");
EXPECT_EQ("(bar(123), after = \"foooooooooooooooooooooooooooooooo\")", kj::str(root)); EXPECT_EQ("(bar = 123, after = \"foooooooooooooooooooooooooooooooo\")", kj::str(root));
EXPECT_EQ( EXPECT_EQ(
"( bar(123),\n" "( bar = 123,\n"
" after = \"foooooooooooooooooooooooooooooooo\" )", " after = \"foooooooooooooooooooooooooooooooo\" )",
prettyPrint(root).flatten()); prettyPrint(root).flatten());
root.setBefore("before"); root.setBefore("before");
EXPECT_EQ("(before = \"before\", bar(123), " EXPECT_EQ("(before = \"before\", bar = 123, "
"after = \"foooooooooooooooooooooooooooooooo\")", kj::str(root)); "after = \"foooooooooooooooooooooooooooooooo\")", kj::str(root));
EXPECT_EQ( EXPECT_EQ(
"( before = \"before\",\n" "( before = \"before\",\n"
" bar(123),\n" " bar = 123,\n"
" after = \"foooooooooooooooooooooooooooooooo\" )", " after = \"foooooooooooooooooooooooooooooooo\" )",
prettyPrint(root).flatten()); prettyPrint(root).flatten());
} }
...@@ -395,7 +397,7 @@ TEST(Stringify, StructUnions) { ...@@ -395,7 +397,7 @@ TEST(Stringify, StructUnions) {
allTypes.setUInt32Field(12345); allTypes.setUInt32Field(12345);
allTypes.setTextField("foo"); allTypes.setTextField("foo");
EXPECT_EQ("(un = allTypes(uInt32Field = 12345, textField = \"foo\"))", kj::str(root)); EXPECT_EQ("(un = (allTypes = (uInt32Field = 12345, textField = \"foo\")))", kj::str(root));
} }
TEST(Stringify, MoreValues) { TEST(Stringify, MoreValues) {
...@@ -405,7 +407,7 @@ TEST(Stringify, MoreValues) { ...@@ -405,7 +407,7 @@ TEST(Stringify, MoreValues) {
EXPECT_EQ("\"\\a\\b\\n\\t\\\"\"", kj::str(DynamicValue::Reader("\a\b\n\t\""))); EXPECT_EQ("\"\\a\\b\\n\\t\\\"\"", kj::str(DynamicValue::Reader("\a\b\n\t\"")));
EXPECT_EQ("foo", kj::str(DynamicValue::Reader(TestEnum::FOO))); EXPECT_EQ("foo", kj::str(DynamicValue::Reader(TestEnum::FOO)));
EXPECT_EQ("123", kj::str(DynamicValue::Reader(static_cast<TestEnum>(123)))); EXPECT_EQ("(123)", kj::str(DynamicValue::Reader(static_cast<TestEnum>(123))));
} }
} // namespace } // namespace
......
...@@ -195,21 +195,34 @@ static kj::StringTree print(const DynamicValue::Reader& value, ...@@ -195,21 +195,34 @@ static kj::StringTree print(const DynamicValue::Reader& value,
kj::Vector<kj::StringTree> printedFields(nonUnionFields.size() + (unionFields.size() != 0)); kj::Vector<kj::StringTree> printedFields(nonUnionFields.size() + (unionFields.size() != 0));
KJ_IF_MAYBE(field, structValue.which()) { // We try to write the union field, if any, in proper order with the rest.
if (structValue.has(*field)) { auto which = structValue.which();
for (auto field: nonUnionFields) {
KJ_IF_MAYBE(unionField, which) {
if (unionField->getIndex() < field.getIndex()) {
if (structValue.has(*unionField)) {
printedFields.add(kj::strTree( printedFields.add(kj::strTree(
field->getProto().getName(), " = ", unionField->getProto().getName(), " = ",
print(structValue.get(*field), whichFieldType(*field), indent.next(), PREFIXED))); print(structValue.get(*unionField), whichFieldType(*unionField),
indent.next(), PREFIXED)));
}
which = nullptr;
} }
} }
for (auto field: nonUnionFields) {
if (structValue.has(field)) { if (structValue.has(field)) {
printedFields.add(kj::strTree( printedFields.add(kj::strTree(
field.getProto().getName(), " = ", field.getProto().getName(), " = ",
print(structValue.get(field), whichFieldType(field), indent.next(), PREFIXED))); print(structValue.get(field), whichFieldType(field), indent.next(), PREFIXED)));
} }
} }
KJ_IF_MAYBE(field, which) {
if (structValue.has(*field)) {
printedFields.add(kj::strTree(
field->getProto().getName(), " = ",
print(structValue.get(*field), whichFieldType(*field), indent.next(), PREFIXED)));
}
}
if (mode == PARENTHESIZED) { if (mode == PARENTHESIZED) {
return indent.delimit(printedFields.releaseAsArray(), mode); return indent.delimit(printedFields.releaseAsArray(), mode);
......
...@@ -291,14 +291,14 @@ struct TestGroups { ...@@ -291,14 +291,14 @@ struct TestGroups {
struct TestUnionDefaults { struct TestUnionDefaults {
s16s8s64s8Set @0 :TestUnion = s16s8s64s8Set @0 :TestUnion =
(union0 = u0f0s16(321), union1 = u1f0s8(123), union2 = u2f0s64(12345678901234567), (union0 = (u0f0s16 = 321), union1 = (u1f0s8 = 123), union2 = (u2f0s64 = 12345678901234567),
union3 = u3f0s8(55)); union3 = (u3f0s8 = 55));
s0sps1s32Set @1 :TestUnion = s0sps1s32Set @1 :TestUnion =
(union0 = u0f1s0(void), union1 = u1f0sp("foo"), union2 = u2f0s1(true), (union0 = (u0f1s0 = void), union1 = (u1f0sp = "foo"), union2 = (u2f0s1 = true),
union3 = u3f0s32(12345678)); union3 = (u3f0s32 = 12345678));
unnamed1 @2 :TestUnnamedUnion = (foo(123)); unnamed1 @2 :TestUnnamedUnion = (foo = 123);
unnamed2 @3 :TestUnnamedUnion = (bar(321), before = "foo", after = "bar"); unnamed2 @3 :TestUnnamedUnion = (bar = 321, before = "foo", after = "bar");
} }
struct TestNestedTypes { struct TestNestedTypes {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment