Commit 263b72ed authored by Kenton Varda's avatar Kenton Varda

Extend JSON union annotations to define a union where all values use the same field name.

parent 02777c54
...@@ -842,10 +842,14 @@ R"({ "names-can_contain!anything Really": "foo", ...@@ -842,10 +842,14 @@ R"({ "names-can_contain!anything Really": "foo",
"innerJson": [123, "hello", {"object": true}], "innerJson": [123, "hello", {"object": true}],
"customFieldHandler": "add-prefix-waldo", "customFieldHandler": "add-prefix-waldo",
"testBase64": "ZnJlZA==", "testBase64": "ZnJlZA==",
"testHex": "706c756768" })"_kj; "testHex": "706c756768",
"bUnion": "renamed-bar",
"bValue": {"hi": 678} })"_kj;
static constexpr kj::StringPtr GOLDEN_ANNOTATED_REVERSE = static constexpr kj::StringPtr GOLDEN_ANNOTATED_REVERSE =
R"({ R"({
"bValue": {"hi": 678},
"bUnion": "renamed-bar",
"testHex": "706c756768", "testHex": "706c756768",
"testBase64": "ZnJlZA==", "testBase64": "ZnJlZA==",
"customFieldHandler": "add-prefix-waldo", "customFieldHandler": "add-prefix-waldo",
...@@ -934,6 +938,8 @@ KJ_TEST("rename fields") { ...@@ -934,6 +938,8 @@ KJ_TEST("rename fields") {
root.setTestBase64("fred"_kj.asBytes()); root.setTestBase64("fred"_kj.asBytes());
root.setTestHex("plugh"_kj.asBytes()); root.setTestHex("plugh"_kj.asBytes());
root.getBUnion().initBar().setHi(678);
auto encoded = json.encode(root.asReader()); auto encoded = json.encode(root.asReader());
KJ_EXPECT(encoded == GOLDEN_ANNOTATED, encoded); KJ_EXPECT(encoded == GOLDEN_ANNOTATED, encoded);
......
...@@ -50,7 +50,7 @@ struct TestJsonAnnotations { ...@@ -50,7 +50,7 @@ struct TestJsonAnnotations {
} }
} }
aUnion :union $Json.flatten() $Json.discriminator("union-type") { aUnion :union $Json.flatten() $Json.discriminator(name = "union-type") {
foo :group $Json.flatten() { foo :group $Json.flatten() {
fooMember @9 :Text; fooMember @9 :Text;
multiMember @10 :UInt32; multiMember @10 :UInt32;
...@@ -77,6 +77,11 @@ struct TestJsonAnnotations { ...@@ -77,6 +77,11 @@ struct TestJsonAnnotations {
testBase64 @18 :Data $Json.base64; testBase64 @18 :Data $Json.base64;
testHex @19 :Data $Json.hex; testHex @19 :Data $Json.hex;
bUnion :union $Json.flatten() $Json.discriminator(valueName = "bValue") {
foo @20 :Text;
bar :group $Json.name("renamed-bar") { hi @21 :UInt32; }
}
} }
struct TestJsonAnnotations2 { struct TestJsonAnnotations2 {
......
...@@ -926,7 +926,9 @@ public: ...@@ -926,7 +926,9 @@ public:
class JsonCodec::AnnotatedHandler final: public JsonCodec::Handler<DynamicStruct> { class JsonCodec::AnnotatedHandler final: public JsonCodec::Handler<DynamicStruct> {
public: public:
AnnotatedHandler(JsonCodec& codec, StructSchema schema, kj::Maybe<kj::StringPtr> discriminator, AnnotatedHandler(JsonCodec& codec, StructSchema schema,
kj::Maybe<json::DiscriminatorOptions::Reader> discriminator,
kj::Maybe<kj::StringPtr> unionDeclName,
kj::Vector<Schema>& dependencies) kj::Vector<Schema>& dependencies)
: schema(schema) { : schema(schema) {
auto schemaProto = schema.getProto(); auto schemaProto = schema.getProto();
...@@ -945,17 +947,29 @@ public: ...@@ -945,17 +947,29 @@ public:
for (auto anno: schemaProto.getAnnotations()) { for (auto anno: schemaProto.getAnnotations()) {
switch (anno.getId()) { switch (anno.getId()) {
case JSON_DISCRIMINATOR_ANNOTATION_ID: case JSON_DISCRIMINATOR_ANNOTATION_ID:
discriminator = anno.getValue().getText(); discriminator = anno.getValue().getStruct().getAs<json::DiscriminatorOptions>();
break; break;
} }
} }
} }
KJ_IF_MAYBE(d, discriminator) { KJ_IF_MAYBE(d, discriminator) {
unionTagName = discriminator; if (d->hasName()) {
fieldsByName.insert(std::make_pair(*d, FieldNameInfo { unionTagName = d->getName();
FieldNameInfo::UNION_TAG, 0, 0, nullptr } else {
})); unionTagName = unionDeclName;
}
KJ_IF_MAYBE(u, unionTagName) {
fieldsByName.insert(std::make_pair(*u, FieldNameInfo {
FieldNameInfo::UNION_TAG, 0, 0, nullptr
}));
}
if (d->hasValueName()) {
fieldsByName.insert(std::make_pair(d->getValueName(), FieldNameInfo {
FieldNameInfo::UNION_VALUE, 0, 0, nullptr
}));
}
} }
discriminantOffset = schemaProto.getStruct().getDiscriminantOffset(); discriminantOffset = schemaProto.getStruct().getDiscriminantOffset();
...@@ -973,7 +987,7 @@ public: ...@@ -973,7 +987,7 @@ public:
FieldInfo info; FieldInfo info;
info.name = fieldName; info.name = fieldName;
kj::Maybe<kj::StringPtr> subDiscriminator; kj::Maybe<json::DiscriminatorOptions::Reader> subDiscriminator;
bool flattened = false; bool flattened = false;
for (auto anno: field.getProto().getAnnotations()) { for (auto anno: field.getProto().getAnnotations()) {
switch (anno.getId()) { switch (anno.getId()) {
...@@ -987,7 +1001,7 @@ public: ...@@ -987,7 +1001,7 @@ public:
break; break;
case JSON_DISCRIMINATOR_ANNOTATION_ID: case JSON_DISCRIMINATOR_ANNOTATION_ID:
KJ_REQUIRE(fieldProto.isGroup(), "only unions can have discriminator"); KJ_REQUIRE(fieldProto.isGroup(), "only unions can have discriminator");
subDiscriminator = anno.getValue().getText(); subDiscriminator = anno.getValue().getStruct().getAs<json::DiscriminatorOptions>();
break; break;
case JSON_BASE64_ANNOTATION_ID: { case JSON_BASE64_ANNOTATION_ID: {
KJ_REQUIRE(field.getType().isData(), "only Data can be marked for base64 encoding"); KJ_REQUIRE(field.getType().isData(), "only Data can be marked for base64 encoding");
...@@ -1004,9 +1018,21 @@ public: ...@@ -1004,9 +1018,21 @@ public:
} }
} }
if (flattened) { if (fieldProto.isGroup()) {
info.flattenHandler = codec.loadAnnotatedHandler( // Load group type handler now, even if not flattened, so that we can pass its
type.asStruct(), subDiscriminator, dependencies); // `subDiscriminator`.
kj::Maybe<kj::StringPtr> subFieldName;
if (flattened) {
// If the group was flattened, then we allow its field name to be used as the
// discriminator name, so that the discriminator doesn't have to explicitly specify a
// name.
subFieldName = fieldName;
}
auto& subHandler = codec.loadAnnotatedHandler(
type.asStruct(), subDiscriminator, subFieldName, dependencies);
if (flattened) {
info.flattenHandler = subHandler;
}
} }
bool isUnionMember = fieldProto.getDiscriminantValue() != schema::Field::NO_DISCRIMINANT; bool isUnionMember = fieldProto.getDiscriminantValue() != schema::Field::NO_DISCRIMINANT;
...@@ -1022,6 +1048,7 @@ public: ...@@ -1022,6 +1048,7 @@ public:
} else { } else {
flattenedName = entry.first; flattenedName = entry.first;
} }
fieldsByName.insert(std::make_pair(flattenedName, FieldNameInfo { fieldsByName.insert(std::make_pair(flattenedName, FieldNameInfo {
isUnionMember ? FieldNameInfo::FLATTENED_FROM_UNION : FieldNameInfo::FLATTENED, isUnionMember ? FieldNameInfo::FLATTENED_FROM_UNION : FieldNameInfo::FLATTENED,
field.getIndex(), (uint)info.prefix.size(), kj::mv(ownName) field.getIndex(), (uint)info.prefix.size(), kj::mv(ownName)
...@@ -1029,12 +1056,26 @@ public: ...@@ -1029,12 +1056,26 @@ public:
} }
} }
info.nameForDiscriminant = info.name;
if (!flattened) { if (!flattened) {
fieldsByName.insert(std::make_pair(info.name, kj::mv(nameInfo))); bool isUnionWithValueName = false;
if (isUnionMember) {
KJ_IF_MAYBE(d, discriminator) {
if (d->hasValueName()) {
info.name = d->getValueName();
isUnionWithValueName = true;
}
}
}
if (!isUnionWithValueName) {
fieldsByName.insert(std::make_pair(info.name, kj::mv(nameInfo)));
}
} }
if (isUnionMember) { if (isUnionMember) {
unionTagValues.insert(std::make_pair(info.name, field)); unionTagValues.insert(std::make_pair(info.nameForDiscriminant, field));
} }
// Look for dependencies that we need to add. // Look for dependencies that we need to add.
...@@ -1110,6 +1151,7 @@ public: ...@@ -1110,6 +1151,7 @@ public:
private: private:
struct FieldInfo { struct FieldInfo {
kj::StringPtr name; kj::StringPtr name;
kj::StringPtr nameForDiscriminant;
kj::Maybe<const AnnotatedHandler&> flattenHandler; kj::Maybe<const AnnotatedHandler&> flattenHandler;
kj::StringPtr prefix; kj::StringPtr prefix;
}; };
...@@ -1130,12 +1172,15 @@ private: ...@@ -1130,12 +1172,15 @@ private:
// The parent struct is a flattened union, and this field is the discriminant tag. It is a // The parent struct is a flattened union, and this field is the discriminant tag. It is a
// string field whose name determines the union type. `index` is not used. // string field whose name determines the union type. `index` is not used.
FLATTENED_FROM_UNION FLATTENED_FROM_UNION,
// The parent struct is a flattened union, and some of the union's members are flattened // The parent struct is a flattened union, and some of the union's members are flattened
// structs or groups, and this field is possibly a member of one or more of them. `index` // structs or groups, and this field is possibly a member of one or more of them. `index`
// is not used, because it's possible that the same field name appears in multiple variants. // is not used, because it's possible that the same field name appears in multiple variants.
// Intsead, the parser must find the union tag, and then can descend and attempt to parse // Intsead, the parser must find the union tag, and then can descend and attempt to parse
// the field in the context of whichever variant is selected. // the field in the context of whichever variant is selected.
UNION_VALUE
// This field is the value of a discriminated union that has `valueName` set.
} type; } type;
uint index; uint index;
...@@ -1203,7 +1248,7 @@ private: ...@@ -1203,7 +1248,7 @@ private:
auto& info = fields[which->getIndex()]; auto& info = fields[which->getIndex()];
KJ_IF_MAYBE(tag, unionTagName) { KJ_IF_MAYBE(tag, unionTagName) {
flattenedFields.add(FlattenedField { flattenedFields.add(FlattenedField {
prefix, *tag, Type(schema::Type::TEXT), Text::Reader(info.name) }); prefix, *tag, Type(schema::Type::TEXT), Text::Reader(info.nameForDiscriminant) });
} }
KJ_IF_MAYBE(handler, info.flattenHandler) { KJ_IF_MAYBE(handler, info.flattenHandler) {
...@@ -1262,6 +1307,17 @@ private: ...@@ -1262,6 +1307,17 @@ private:
.decodeField(codec, name.slice(info.prefixLength), value, .decodeField(codec, name.slice(info.prefixLength), value,
output.get(variant).as<DynamicStruct>(), unionsSeen); output.get(variant).as<DynamicStruct>(), unionsSeen);
} }
case FieldNameInfo::UNION_VALUE: {
const void* ptr = getUnionInstanceIdentifier(output);
if (unionsSeen.count(ptr) == 0) {
// We haven't seen the union tag yet, so we can't parse this field yet. Try again later.
return false;
}
auto variant = KJ_ASSERT_NONNULL(output.which());
codec.decodeField(variant, value, Orphanage::getForMessageContaining(output), output);
return true;
}
} }
KJ_UNREACHABLE; KJ_UNREACHABLE;
...@@ -1367,12 +1423,13 @@ private: ...@@ -1367,12 +1423,13 @@ private:
}; };
JsonCodec::AnnotatedHandler& JsonCodec::loadAnnotatedHandler( JsonCodec::AnnotatedHandler& JsonCodec::loadAnnotatedHandler(
StructSchema schema, kj::Maybe<kj::StringPtr> discriminator, StructSchema schema, kj::Maybe<json::DiscriminatorOptions::Reader> discriminator,
kj::Vector<Schema>& dependencies) { kj::Maybe<kj::StringPtr> unionDeclName, kj::Vector<Schema>& dependencies) {
auto insertResult = impl->annotatedHandlers.insert(std::make_pair(schema, nullptr)); auto insertResult = impl->annotatedHandlers.insert(std::make_pair(schema, nullptr));
if (insertResult.second) { if (insertResult.second) {
// Not seen before. // Not seen before.
auto newHandler = kj::heap<AnnotatedHandler>(*this, schema, discriminator, dependencies); auto newHandler = kj::heap<AnnotatedHandler>(
*this, schema, discriminator, unionDeclName, dependencies);
auto& result = *newHandler; auto& result = *newHandler;
insertResult.first->second = kj::mv(newHandler); insertResult.first->second = kj::mv(newHandler);
addTypeHandler(schema, result); addTypeHandler(schema, result);
...@@ -1393,7 +1450,7 @@ void JsonCodec::handleByAnnotation(Schema schema) { ...@@ -1393,7 +1450,7 @@ void JsonCodec::handleByAnnotation(Schema schema) {
addTypeHandler(schema.asStruct(), GLOBAL_HANDLER); addTypeHandler(schema.asStruct(), GLOBAL_HANDLER);
} else { } else {
kj::Vector<Schema> dependencies; kj::Vector<Schema> dependencies;
loadAnnotatedHandler(schema.asStruct(), nullptr, dependencies); loadAnnotatedHandler(schema.asStruct(), nullptr, nullptr, dependencies);
for (auto dep: dependencies) { for (auto dep: dependencies) {
handleByAnnotation(dep); handleByAnnotation(dep);
} }
......
...@@ -87,11 +87,23 @@ struct FlattenOptions { ...@@ -87,11 +87,23 @@ struct FlattenOptions {
# Optional: Adds the given prefix to flattened field names. # Optional: Adds the given prefix to flattened field names.
} }
annotation discriminator @0xcfa794e8d19a0162 (struct, union): Text; annotation discriminator @0xcfa794e8d19a0162 (struct, union): DiscriminatorOptions;
# Specifies that a union's variant will be decided not by which fields are present, but instead # Specifies that a union's variant will be decided not by which fields are present, but instead
# by a special discriminator field with the given name. The value of the discriminator field is # by a special discriminator field. The value of the discriminator field is a string naming which
# a string naming which variant is active. This allows the members of the union to have the # variant is active. This allows the members of the union to have the $jsonFlatten annotation, or
# $jsonFlatten annotation. # to all have the same name.
struct DiscriminatorOptions {
name @0 :Text;
# The name of the discriminator field. Defaults to matching the name of the union.
valueName @1 :Text;
# If non-null, specifies that the union's value shall have the given field name, rather than the
# value's name. In this case the union's variant can only be determined by looking at the
# discriminant field, not by inspecting which value field is present.
#
# It is an error to use `valueName` while also declaring some variants as $flatten.
}
annotation base64 @0xd7d879450a253e4b (field): Void; annotation base64 @0xd7d879450a253e4b (field): Void;
# Place on a field of type `Data` to indicate that its JSON representation is a Base64 string. # Place on a field of type `Data` to indicate that its JSON representation is a Base64 string.
......
...@@ -414,8 +414,8 @@ static const ::capnp::_::AlignedData<22> b_cfa794e8d19a0162 = { ...@@ -414,8 +414,8 @@ static const ::capnp::_::AlignedData<22> b_cfa794e8d19a0162 = {
100, 105, 115, 99, 114, 105, 109, 105, 100, 105, 115, 99, 114, 105, 109, 105,
110, 97, 116, 111, 114, 0, 0, 0, 110, 97, 116, 111, 114, 0, 0, 0,
0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0,
12, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 25, 83, 62, 41, 12, 194, 248, 194,
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, }
}; };
...@@ -426,6 +426,128 @@ const ::capnp::_::RawSchema s_cfa794e8d19a0162 = { ...@@ -426,6 +426,128 @@ const ::capnp::_::RawSchema s_cfa794e8d19a0162 = {
0, 0, nullptr, nullptr, nullptr, { &s_cfa794e8d19a0162, nullptr, nullptr, 0, 0, nullptr } 0, 0, nullptr, nullptr, nullptr, { &s_cfa794e8d19a0162, nullptr, nullptr, 0, 0, nullptr }
}; };
#endif // !CAPNP_LITE #endif // !CAPNP_LITE
static const ::capnp::_::AlignedData<51> b_c2f8c20c293e5319 = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
25, 83, 62, 41, 12, 194, 248, 194,
24, 0, 0, 0, 1, 0, 0, 0,
52, 94, 58, 164, 151, 146, 249, 142,
2, 0, 7, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
21, 0, 0, 0, 106, 1, 0, 0,
41, 0, 0, 0, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
37, 0, 0, 0, 119, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
99, 97, 112, 110, 112, 47, 99, 111,
109, 112, 97, 116, 47, 106, 115, 111,
110, 46, 99, 97, 112, 110, 112, 58,
68, 105, 115, 99, 114, 105, 109, 105,
110, 97, 116, 111, 114, 79, 112, 116,
105, 111, 110, 115, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 1, 0,
8, 0, 0, 0, 3, 0, 4, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
41, 0, 0, 0, 42, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
36, 0, 0, 0, 3, 0, 1, 0,
48, 0, 0, 0, 2, 0, 1, 0,
1, 0, 0, 0, 1, 0, 0, 0,
0, 0, 1, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
45, 0, 0, 0, 82, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
44, 0, 0, 0, 3, 0, 1, 0,
56, 0, 0, 0, 2, 0, 1, 0,
110, 97, 109, 101, 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,
12, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
118, 97, 108, 117, 101, 78, 97, 109,
101, 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,
12, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, }
};
::capnp::word const* const bp_c2f8c20c293e5319 = b_c2f8c20c293e5319.words;
#if !CAPNP_LITE
static const uint16_t m_c2f8c20c293e5319[] = {0, 1};
static const uint16_t i_c2f8c20c293e5319[] = {0, 1};
const ::capnp::_::RawSchema s_c2f8c20c293e5319 = {
0xc2f8c20c293e5319, b_c2f8c20c293e5319.words, 51, nullptr, m_c2f8c20c293e5319,
0, 2, i_c2f8c20c293e5319, nullptr, nullptr, { &s_c2f8c20c293e5319, nullptr, nullptr, 0, 0, nullptr }
};
#endif // !CAPNP_LITE
static const ::capnp::_::AlignedData<21> b_d7d879450a253e4b = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
75, 62, 37, 10, 69, 121, 216, 215,
24, 0, 0, 0, 5, 0, 32, 0,
52, 94, 58, 164, 151, 146, 249, 142,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
21, 0, 0, 0, 250, 0, 0, 0,
33, 0, 0, 0, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
28, 0, 0, 0, 3, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
99, 97, 112, 110, 112, 47, 99, 111,
109, 112, 97, 116, 47, 106, 115, 111,
110, 46, 99, 97, 112, 110, 112, 58,
98, 97, 115, 101, 54, 52, 0, 0,
0, 0, 0, 0, 1, 0, 1, 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, }
};
::capnp::word const* const bp_d7d879450a253e4b = b_d7d879450a253e4b.words;
#if !CAPNP_LITE
const ::capnp::_::RawSchema s_d7d879450a253e4b = {
0xd7d879450a253e4b, b_d7d879450a253e4b.words, 21, nullptr, nullptr,
0, 0, nullptr, nullptr, nullptr, { &s_d7d879450a253e4b, nullptr, nullptr, 0, 0, nullptr }
};
#endif // !CAPNP_LITE
static const ::capnp::_::AlignedData<21> b_f061e22f0ae5c7b5 = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
181, 199, 229, 10, 47, 226, 97, 240,
24, 0, 0, 0, 5, 0, 32, 0,
52, 94, 58, 164, 151, 146, 249, 142,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
21, 0, 0, 0, 226, 0, 0, 0,
33, 0, 0, 0, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
28, 0, 0, 0, 3, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
99, 97, 112, 110, 112, 47, 99, 111,
109, 112, 97, 116, 47, 106, 115, 111,
110, 46, 99, 97, 112, 110, 112, 58,
104, 101, 120, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 1, 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, }
};
::capnp::word const* const bp_f061e22f0ae5c7b5 = b_f061e22f0ae5c7b5.words;
#if !CAPNP_LITE
const ::capnp::_::RawSchema s_f061e22f0ae5c7b5 = {
0xf061e22f0ae5c7b5, b_f061e22f0ae5c7b5.words, 21, nullptr, nullptr,
0, 0, nullptr, nullptr, nullptr, { &s_f061e22f0ae5c7b5, nullptr, nullptr, 0, 0, nullptr }
};
#endif // !CAPNP_LITE
} // namespace schemas } // namespace schemas
} // namespace capnp } // namespace capnp
...@@ -466,6 +588,14 @@ constexpr ::capnp::Kind FlattenOptions::_capnpPrivate::kind; ...@@ -466,6 +588,14 @@ constexpr ::capnp::Kind FlattenOptions::_capnpPrivate::kind;
constexpr ::capnp::_::RawSchema const* FlattenOptions::_capnpPrivate::schema; constexpr ::capnp::_::RawSchema const* FlattenOptions::_capnpPrivate::schema;
#endif // !CAPNP_LITE #endif // !CAPNP_LITE
// DiscriminatorOptions
constexpr uint16_t DiscriminatorOptions::_capnpPrivate::dataWordSize;
constexpr uint16_t DiscriminatorOptions::_capnpPrivate::pointerCount;
#if !CAPNP_LITE
constexpr ::capnp::Kind DiscriminatorOptions::_capnpPrivate::kind;
constexpr ::capnp::_::RawSchema const* DiscriminatorOptions::_capnpPrivate::schema;
#endif // !CAPNP_LITE
} // namespace } // namespace
} // namespace } // namespace
......
...@@ -24,6 +24,9 @@ CAPNP_DECLARE_SCHEMA(fa5b1fd61c2e7c3d); ...@@ -24,6 +24,9 @@ CAPNP_DECLARE_SCHEMA(fa5b1fd61c2e7c3d);
CAPNP_DECLARE_SCHEMA(82d3e852af0336bf); CAPNP_DECLARE_SCHEMA(82d3e852af0336bf);
CAPNP_DECLARE_SCHEMA(c4df13257bc2ea61); CAPNP_DECLARE_SCHEMA(c4df13257bc2ea61);
CAPNP_DECLARE_SCHEMA(cfa794e8d19a0162); CAPNP_DECLARE_SCHEMA(cfa794e8d19a0162);
CAPNP_DECLARE_SCHEMA(c2f8c20c293e5319);
CAPNP_DECLARE_SCHEMA(d7d879450a253e4b);
CAPNP_DECLARE_SCHEMA(f061e22f0ae5c7b5);
} // namespace schemas } // namespace schemas
} // namespace capnp } // namespace capnp
...@@ -102,6 +105,21 @@ struct FlattenOptions { ...@@ -102,6 +105,21 @@ struct FlattenOptions {
}; };
}; };
struct DiscriminatorOptions {
DiscriminatorOptions() = delete;
class Reader;
class Builder;
class Pipeline;
struct _capnpPrivate {
CAPNP_DECLARE_STRUCT_HEADER(c2f8c20c293e5319, 0, 2)
#if !CAPNP_LITE
static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
#endif // !CAPNP_LITE
};
};
// ======================================================================================= // =======================================================================================
class Value::Reader { class Value::Reader {
...@@ -510,6 +528,97 @@ private: ...@@ -510,6 +528,97 @@ private:
}; };
#endif // !CAPNP_LITE #endif // !CAPNP_LITE
class DiscriminatorOptions::Reader {
public:
typedef DiscriminatorOptions Reads;
Reader() = default;
inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}
inline ::capnp::MessageSize totalSize() const {
return _reader.totalSize().asPublic();
}
#if !CAPNP_LITE
inline ::kj::StringTree toString() const {
return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
}
#endif // !CAPNP_LITE
inline bool hasName() const;
inline ::capnp::Text::Reader getName() const;
inline bool hasValueName() const;
inline ::capnp::Text::Reader getValueName() const;
private:
::capnp::_::StructReader _reader;
template <typename, ::capnp::Kind>
friend struct ::capnp::ToDynamic_;
template <typename, ::capnp::Kind>
friend struct ::capnp::_::PointerHelpers;
template <typename, ::capnp::Kind>
friend struct ::capnp::List;
friend class ::capnp::MessageBuilder;
friend class ::capnp::Orphanage;
};
class DiscriminatorOptions::Builder {
public:
typedef DiscriminatorOptions Builds;
Builder() = delete; // Deleted to discourage incorrect usage.
// You can explicitly initialize to nullptr instead.
inline Builder(decltype(nullptr)) {}
inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
inline operator Reader() const { return Reader(_builder.asReader()); }
inline Reader asReader() const { return *this; }
inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif // !CAPNP_LITE
inline bool hasName();
inline ::capnp::Text::Builder getName();
inline void setName( ::capnp::Text::Reader value);
inline ::capnp::Text::Builder initName(unsigned int size);
inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value);
inline ::capnp::Orphan< ::capnp::Text> disownName();
inline bool hasValueName();
inline ::capnp::Text::Builder getValueName();
inline void setValueName( ::capnp::Text::Reader value);
inline ::capnp::Text::Builder initValueName(unsigned int size);
inline void adoptValueName(::capnp::Orphan< ::capnp::Text>&& value);
inline ::capnp::Orphan< ::capnp::Text> disownValueName();
private:
::capnp::_::StructBuilder _builder;
template <typename, ::capnp::Kind>
friend struct ::capnp::ToDynamic_;
friend class ::capnp::Orphanage;
template <typename, ::capnp::Kind>
friend struct ::capnp::_::PointerHelpers;
};
#if !CAPNP_LITE
class DiscriminatorOptions::Pipeline {
public:
typedef DiscriminatorOptions Pipelines;
inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
: _typeless(kj::mv(typeless)) {}
private:
::capnp::AnyPointer::Pipeline _typeless;
friend class ::capnp::PipelineHook;
template <typename, ::capnp::Kind>
friend struct ::capnp::ToDynamic_;
};
#endif // !CAPNP_LITE
// ======================================================================================= // =======================================================================================
inline ::capnp::json::Value::Which Value::Reader::which() const { inline ::capnp::json::Value::Which Value::Reader::which() const {
...@@ -992,6 +1101,74 @@ inline ::capnp::Orphan< ::capnp::Text> FlattenOptions::Builder::disownPrefix() { ...@@ -992,6 +1101,74 @@ inline ::capnp::Orphan< ::capnp::Text> FlattenOptions::Builder::disownPrefix() {
::capnp::bounded<0>() * ::capnp::POINTERS)); ::capnp::bounded<0>() * ::capnp::POINTERS));
} }
inline bool DiscriminatorOptions::Reader::hasName() const {
return !_reader.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool DiscriminatorOptions::Builder::hasName() {
return !_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline ::capnp::Text::Reader DiscriminatorOptions::Reader::getName() const {
return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::capnp::Text::Builder DiscriminatorOptions::Builder::getName() {
return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void DiscriminatorOptions::Builder::setName( ::capnp::Text::Reader value) {
::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline ::capnp::Text::Builder DiscriminatorOptions::Builder::initName(unsigned int size) {
return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS), size);
}
inline void DiscriminatorOptions::Builder::adoptName(
::capnp::Orphan< ::capnp::Text>&& value) {
::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::Text> DiscriminatorOptions::Builder::disownName() {
return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline bool DiscriminatorOptions::Reader::hasValueName() const {
return !_reader.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline bool DiscriminatorOptions::Builder::hasValueName() {
return !_builder.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline ::capnp::Text::Reader DiscriminatorOptions::Reader::getValueName() const {
return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline ::capnp::Text::Builder DiscriminatorOptions::Builder::getValueName() {
return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline void DiscriminatorOptions::Builder::setValueName( ::capnp::Text::Reader value) {
::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS), value);
}
inline ::capnp::Text::Builder DiscriminatorOptions::Builder::initValueName(unsigned int size) {
return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS), size);
}
inline void DiscriminatorOptions::Builder::adoptValueName(
::capnp::Orphan< ::capnp::Text>&& value) {
::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::Text> DiscriminatorOptions::Builder::disownValueName() {
return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField(
::capnp::bounded<1>() * ::capnp::POINTERS));
}
} // namespace } // namespace
} // namespace } // namespace
...@@ -247,9 +247,11 @@ private: ...@@ -247,9 +247,11 @@ private:
void addTypeHandlerImpl(Type type, HandlerBase& handler); void addTypeHandlerImpl(Type type, HandlerBase& handler);
void addFieldHandlerImpl(StructSchema::Field field, Type type, HandlerBase& handler); void addFieldHandlerImpl(StructSchema::Field field, Type type, HandlerBase& handler);
AnnotatedHandler& loadAnnotatedHandler(StructSchema schema, AnnotatedHandler& loadAnnotatedHandler(
kj::Maybe<kj::StringPtr> discriminator, StructSchema schema,
kj::Vector<Schema>& dependencies); kj::Maybe<json::DiscriminatorOptions::Reader> discriminator,
kj::Maybe<kj::StringPtr> unionDeclName,
kj::Vector<Schema>& dependencies);
}; };
// ======================================================================================= // =======================================================================================
......
...@@ -15,4 +15,6 @@ ...@@ -15,4 +15,6 @@
"enums": ["qux", "renamed-bar", "foo", "renamed-baz"], "enums": ["qux", "renamed-bar", "foo", "renamed-baz"],
"innerJson": [123, "hello", {"object": true}], "innerJson": [123, "hello", {"object": true}],
"testBase64": "ZnJlZA==", "testBase64": "ZnJlZA==",
"testHex": "706c756768" } "testHex": "706c756768",
"bUnion": "renamed-bar",
"bValue": {"hi": 678} }
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