mirror of
https://github.com/google/flatbuffers.git
synced 2026-07-02 19:28:17 +00:00
Add support for parsing proto map fields (#7613)
* Add support for proto 3 map to fbs gen * Run clang-format * Update proto golden test * Rename variables * Remove iostream * Remove iostream * Run clang format Co-authored-by: Derek Bailey <derekbailey@google.com>
This commit is contained in:
@@ -489,11 +489,11 @@ inline bool IsVector(const Type &type) {
|
|||||||
return type.base_type == BASE_TYPE_VECTOR;
|
return type.base_type == BASE_TYPE_VECTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsVectorOfStruct(const Type& type) {
|
inline bool IsVectorOfStruct(const Type &type) {
|
||||||
return IsVector(type) && IsStruct(type.VectorType());
|
return IsVector(type) && IsStruct(type.VectorType());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsVectorOfTable(const Type& type) {
|
inline bool IsVectorOfTable(const Type &type) {
|
||||||
return IsVector(type) && IsTable(type.VectorType());
|
return IsVector(type) && IsTable(type.VectorType());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1031,6 +1031,7 @@ class Parser : public ParserState {
|
|||||||
FLATBUFFERS_CHECKED_ERROR ParseService(const char *filename);
|
FLATBUFFERS_CHECKED_ERROR ParseService(const char *filename);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseProtoFields(StructDef *struct_def,
|
FLATBUFFERS_CHECKED_ERROR ParseProtoFields(StructDef *struct_def,
|
||||||
bool isextend, bool inside_oneof);
|
bool isextend, bool inside_oneof);
|
||||||
|
FLATBUFFERS_CHECKED_ERROR ParseProtoMapField(StructDef *struct_def);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseProtoOption();
|
FLATBUFFERS_CHECKED_ERROR ParseProtoOption();
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseProtoKey();
|
FLATBUFFERS_CHECKED_ERROR ParseProtoKey();
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseProtoDecl();
|
FLATBUFFERS_CHECKED_ERROR ParseProtoDecl();
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ std::string GenerateFBS(const Parser &parser, const std::string &file_name) {
|
|||||||
schema += " " + field.name + ":" + GenType(field.value.type);
|
schema += " " + field.name + ":" + GenType(field.value.type);
|
||||||
if (field.value.constant != "0") schema += " = " + field.value.constant;
|
if (field.value.constant != "0") schema += " = " + field.value.constant;
|
||||||
if (field.IsRequired()) schema += " (required)";
|
if (field.IsRequired()) schema += " (required)";
|
||||||
|
if (field.key) schema += " (key)";
|
||||||
schema += ";\n";
|
schema += ";\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -507,6 +507,8 @@ CheckedError Parser::Next() {
|
|||||||
case ')':
|
case ')':
|
||||||
case '[':
|
case '[':
|
||||||
case ']':
|
case ']':
|
||||||
|
case '<':
|
||||||
|
case '>':
|
||||||
case ',':
|
case ',':
|
||||||
case ':':
|
case ':':
|
||||||
case ';':
|
case ';':
|
||||||
@@ -2896,6 +2898,8 @@ CheckedError Parser::ParseProtoFields(StructDef *struct_def, bool isextend,
|
|||||||
NEXT();
|
NEXT();
|
||||||
while (!Is(';')) { NEXT(); } // A variety of formats, just skip.
|
while (!Is(';')) { NEXT(); } // A variety of formats, just skip.
|
||||||
NEXT();
|
NEXT();
|
||||||
|
} else if (IsIdent("map")) {
|
||||||
|
ECHECK(ParseProtoMapField(struct_def));
|
||||||
} else {
|
} else {
|
||||||
std::vector<std::string> field_comment = doc_comment_;
|
std::vector<std::string> field_comment = doc_comment_;
|
||||||
// Parse the qualifier.
|
// Parse the qualifier.
|
||||||
@@ -3030,6 +3034,41 @@ CheckedError Parser::ParseProtoFields(StructDef *struct_def, bool isextend,
|
|||||||
return NoError();
|
return NoError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CheckedError Parser::ParseProtoMapField(StructDef *struct_def) {
|
||||||
|
NEXT();
|
||||||
|
EXPECT('<');
|
||||||
|
Type key_type;
|
||||||
|
ECHECK(ParseType(key_type));
|
||||||
|
EXPECT(',');
|
||||||
|
Type value_type;
|
||||||
|
ECHECK(ParseType(value_type));
|
||||||
|
EXPECT('>');
|
||||||
|
auto field_name = attribute_;
|
||||||
|
NEXT();
|
||||||
|
EXPECT('=');
|
||||||
|
EXPECT(kTokenIntegerConstant);
|
||||||
|
EXPECT(';');
|
||||||
|
|
||||||
|
auto entry_table_name = ConvertCase(field_name, Case::kUpperCamel) + "Entry";
|
||||||
|
StructDef *entry_table;
|
||||||
|
ECHECK(StartStruct(entry_table_name, &entry_table));
|
||||||
|
entry_table->has_key = true;
|
||||||
|
FieldDef *key_field;
|
||||||
|
ECHECK(AddField(*entry_table, "key", key_type, &key_field));
|
||||||
|
key_field->key = true;
|
||||||
|
FieldDef *value_field;
|
||||||
|
ECHECK(AddField(*entry_table, "value", value_type, &value_field));
|
||||||
|
|
||||||
|
Type field_type;
|
||||||
|
field_type.base_type = BASE_TYPE_VECTOR;
|
||||||
|
field_type.element = BASE_TYPE_STRUCT;
|
||||||
|
field_type.struct_def = entry_table;
|
||||||
|
FieldDef *field;
|
||||||
|
ECHECK(AddField(*struct_def, field_name, field_type, &field));
|
||||||
|
|
||||||
|
return NoError();
|
||||||
|
}
|
||||||
|
|
||||||
CheckedError Parser::ParseProtoKey() {
|
CheckedError Parser::ParseProtoKey() {
|
||||||
if (token_ == '(') {
|
if (token_ == '(') {
|
||||||
NEXT();
|
NEXT();
|
||||||
|
|||||||
@@ -201,4 +201,4 @@ void ParseProtoBufAsciiTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace tests
|
} // namespace tests
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|||||||
24
tests/prototest/GenerateProtoGoldens.sh
Executable file
24
tests/prototest/GenerateProtoGoldens.sh
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Copyright 2022 Google Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
pushd "$(dirname $0)" >/dev/null
|
||||||
|
|
||||||
|
./../../flatc --proto test.proto && mv test.fbs test_include.golden
|
||||||
|
./../../flatc --proto --gen-all test.proto && mv test.fbs test.golden
|
||||||
|
./../../flatc --proto --oneof-union test.proto && mv test.fbs test_union_include.golden
|
||||||
|
./../../flatc --proto --gen-all --oneof-union test.proto && mv test.fbs test_union.golden
|
||||||
|
./../../flatc --proto --gen-all --proto-namespace-suffix test_namespace_suffix test.proto && mv test.fbs test_suffix.golden
|
||||||
|
./../../flatc --proto --gen-all --proto-namespace-suffix test_namespace_suffix --oneof-union test.proto && mv test.fbs test_union_suffix.golden
|
||||||
@@ -54,6 +54,8 @@ table ProtoMessage {
|
|||||||
u:float = +inf;
|
u:float = +inf;
|
||||||
v:float = +inf;
|
v:float = +inf;
|
||||||
w:float = -inf;
|
w:float = -inf;
|
||||||
|
grades:[proto.test.ProtoMessage_.GradesEntry];
|
||||||
|
other_message_map:[proto.test.ProtoMessage_.OtherMessageMapEntry];
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace proto.test.ProtoMessage_;
|
namespace proto.test.ProtoMessage_;
|
||||||
@@ -73,3 +75,13 @@ table Anonymous0 {
|
|||||||
t:proto.test.ProtoMessage_.OtherMessage;
|
t:proto.test.ProtoMessage_.OtherMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table GradesEntry {
|
||||||
|
key:string (key);
|
||||||
|
value:float;
|
||||||
|
}
|
||||||
|
|
||||||
|
table OtherMessageMapEntry {
|
||||||
|
key:string (key);
|
||||||
|
value:proto.test.ProtoMessage_.OtherMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,4 +71,7 @@ message ProtoMessage {
|
|||||||
optional float u = 34 [default = inf];
|
optional float u = 34 [default = inf];
|
||||||
optional float v = 35 [default = +inf];
|
optional float v = 35 [default = +inf];
|
||||||
optional float w = 36 [default = -inf];
|
optional float w = 36 [default = -inf];
|
||||||
|
|
||||||
|
map<string, float> grades = 37;
|
||||||
|
map<string, OtherMessage> other_message_map = 38;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ table ProtoMessage {
|
|||||||
u:float = +inf;
|
u:float = +inf;
|
||||||
v:float = +inf;
|
v:float = +inf;
|
||||||
w:float = -inf;
|
w:float = -inf;
|
||||||
|
grades:[proto.test.ProtoMessage_.GradesEntry];
|
||||||
|
other_message_map:[proto.test.ProtoMessage_.OtherMessageMapEntry];
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace proto.test.ProtoMessage_;
|
namespace proto.test.ProtoMessage_;
|
||||||
@@ -71,3 +73,13 @@ table Anonymous0 {
|
|||||||
t:proto.test.ProtoMessage_.OtherMessage;
|
t:proto.test.ProtoMessage_.OtherMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table GradesEntry {
|
||||||
|
key:string (key);
|
||||||
|
value:float;
|
||||||
|
}
|
||||||
|
|
||||||
|
table OtherMessageMapEntry {
|
||||||
|
key:string (key);
|
||||||
|
value:proto.test.ProtoMessage_.OtherMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,8 @@ table ProtoMessage {
|
|||||||
u:float = +inf;
|
u:float = +inf;
|
||||||
v:float = +inf;
|
v:float = +inf;
|
||||||
w:float = -inf;
|
w:float = -inf;
|
||||||
|
grades:[proto.test.test_namespace_suffix.ProtoMessage_.GradesEntry];
|
||||||
|
other_message_map:[proto.test.test_namespace_suffix.ProtoMessage_.OtherMessageMapEntry];
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace proto.test.test_namespace_suffix.ProtoMessage_;
|
namespace proto.test.test_namespace_suffix.ProtoMessage_;
|
||||||
@@ -73,3 +75,13 @@ table Anonymous0 {
|
|||||||
t:proto.test.test_namespace_suffix.ProtoMessage_.OtherMessage;
|
t:proto.test.test_namespace_suffix.ProtoMessage_.OtherMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table GradesEntry {
|
||||||
|
key:string (key);
|
||||||
|
value:float;
|
||||||
|
}
|
||||||
|
|
||||||
|
table OtherMessageMapEntry {
|
||||||
|
key:string (key);
|
||||||
|
value:proto.test.test_namespace_suffix.ProtoMessage_.OtherMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ table ProtoMessage {
|
|||||||
u:float = +inf;
|
u:float = +inf;
|
||||||
v:float = +inf;
|
v:float = +inf;
|
||||||
w:float = -inf;
|
w:float = -inf;
|
||||||
|
grades:[proto.test.ProtoMessage_.GradesEntry];
|
||||||
|
other_message_map:[proto.test.ProtoMessage_.OtherMessageMapEntry];
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace proto.test.ProtoMessage_;
|
namespace proto.test.ProtoMessage_;
|
||||||
@@ -75,3 +77,13 @@ table OtherMessage {
|
|||||||
foo_bar_baz:proto.test.ProtoMessage_.OtherMessage_.ProtoEnum;
|
foo_bar_baz:proto.test.ProtoMessage_.OtherMessage_.ProtoEnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table GradesEntry {
|
||||||
|
key:string (key);
|
||||||
|
value:float;
|
||||||
|
}
|
||||||
|
|
||||||
|
table OtherMessageMapEntry {
|
||||||
|
key:string (key);
|
||||||
|
value:proto.test.ProtoMessage_.OtherMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,8 @@ table ProtoMessage {
|
|||||||
u:float = +inf;
|
u:float = +inf;
|
||||||
v:float = +inf;
|
v:float = +inf;
|
||||||
w:float = -inf;
|
w:float = -inf;
|
||||||
|
grades:[proto.test.ProtoMessage_.GradesEntry];
|
||||||
|
other_message_map:[proto.test.ProtoMessage_.OtherMessageMapEntry];
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace proto.test.ProtoMessage_;
|
namespace proto.test.ProtoMessage_;
|
||||||
@@ -73,3 +75,13 @@ table OtherMessage {
|
|||||||
foo_bar_baz:proto.test.ProtoMessage_.OtherMessage_.ProtoEnum;
|
foo_bar_baz:proto.test.ProtoMessage_.OtherMessage_.ProtoEnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table GradesEntry {
|
||||||
|
key:string (key);
|
||||||
|
value:float;
|
||||||
|
}
|
||||||
|
|
||||||
|
table OtherMessageMapEntry {
|
||||||
|
key:string (key);
|
||||||
|
value:proto.test.ProtoMessage_.OtherMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ table ProtoMessage {
|
|||||||
u:float = +inf;
|
u:float = +inf;
|
||||||
v:float = +inf;
|
v:float = +inf;
|
||||||
w:float = -inf;
|
w:float = -inf;
|
||||||
|
grades:[proto.test.test_namespace_suffix.ProtoMessage_.GradesEntry];
|
||||||
|
other_message_map:[proto.test.test_namespace_suffix.ProtoMessage_.OtherMessageMapEntry];
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace proto.test.test_namespace_suffix.ProtoMessage_;
|
namespace proto.test.test_namespace_suffix.ProtoMessage_;
|
||||||
@@ -75,3 +77,13 @@ table OtherMessage {
|
|||||||
foo_bar_baz:proto.test.test_namespace_suffix.ProtoMessage_.OtherMessage_.ProtoEnum;
|
foo_bar_baz:proto.test.test_namespace_suffix.ProtoMessage_.OtherMessage_.ProtoEnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table GradesEntry {
|
||||||
|
key:string (key);
|
||||||
|
value:float;
|
||||||
|
}
|
||||||
|
|
||||||
|
table OtherMessageMapEntry {
|
||||||
|
key:string (key);
|
||||||
|
value:proto.test.test_namespace_suffix.ProtoMessage_.OtherMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user