From: Michael Beardsworth Date: Mon, 6 Jan 2020 18:00:59 +0000 (-0800) Subject: (Optionally) add an additional suffix namespace to generated fbs files. (#5698) X-Git-Tag: v1.12.0~47 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=21b7061963233fddc726a3dfb9a4131a4ce6cb0d;p=platform%2Fupstream%2Fflatbuffers.git (Optionally) add an additional suffix namespace to generated fbs files. (#5698) This change allows for the generation of fbs files (from proto) that don't contain name collisions with the protobuf generated C++ code, allowing both the proto and fbs message types to be linked into the same binary. --- diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 792103c..1f013a8 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -557,6 +557,7 @@ struct IDLOptions { bool java_primitive_has_method; std::vector cpp_includes; std::string cpp_std; + std::string proto_namespace_suffix; // Possible options for the more general generator below. enum Language { diff --git a/src/flatc.cpp b/src/flatc.cpp index 8df2014..f13b336 100644 --- a/src/flatc.cpp +++ b/src/flatc.cpp @@ -134,6 +134,8 @@ std::string FlatCompiler::GetUsageString(const char *program_name) const { " This may crash flatc given a mismatched schema.\n" " --size-prefixed Input binaries are size prefixed buffers.\n" " --proto Input is a .proto, translate to .fbs.\n" + " --proto-namespace-suffix Add this namespace to any flatbuffers generated\n" + " SUFFIX from protobufs.\n" " --oneof-union Translate .proto oneofs to flatbuffer unions.\n" " --grpc Generate GRPC interfaces for the specified languages.\n" " --schema Serialize schemas instead of JSON (use with -b).\n" @@ -299,6 +301,9 @@ int FlatCompiler::Compile(int argc, const char **argv) { binary_files_from = filenames.size(); } else if (arg == "--proto") { opts.proto_mode = true; + } else if (arg == "--proto-namespace-suffix") { + if (++argi >= argc) Error("missing namespace suffix" + arg, true); + opts.proto_namespace_suffix = argv[argi]; } else if (arg == "--oneof-union") { opts.proto_oneof_union = true; } else if (arg == "--schema") { diff --git a/src/idl_gen_fbs.cpp b/src/idl_gen_fbs.cpp index d3bee62..d2e1068 100644 --- a/src/idl_gen_fbs.cpp +++ b/src/idl_gen_fbs.cpp @@ -63,6 +63,13 @@ std::string GenerateFBS(const Parser &parser, const std::string &file_name) { for (size_t i = 0; i < ns.from_table; i++) { ns.components[ns.components.size() - 1 - i] += "_"; } + + if (parser.opts.proto_mode && !parser.opts.proto_namespace_suffix.empty()) { + // Since we know that all these namespaces come from a .proto, and all are + // being converted, we can simply apply this suffix to all of them. + ns.components.insert(ns.components.end() - ns.from_table, + parser.opts.proto_namespace_suffix); + } } std::string schema; diff --git a/tests/BUILD b/tests/BUILD index 6308613..b61824c 100644 --- a/tests/BUILD +++ b/tests/BUILD @@ -45,8 +45,10 @@ cc_test( ":prototest/test.golden", ":prototest/test.proto", ":prototest/test_include.golden", + ":prototest/test_suffix.golden", ":prototest/test_union.golden", ":prototest/test_union_include.golden", + ":prototest/test_union_suffix.golden", ":unicode_test.json", ":union_vector/union_vector.fbs", ":union_vector/union_vector.json", diff --git a/tests/prototest/test_suffix.golden b/tests/prototest/test_suffix.golden new file mode 100644 index 0000000..94ffd26 --- /dev/null +++ b/tests/prototest/test_suffix.golden @@ -0,0 +1,59 @@ +// Generated from test.proto + +namespace proto.test.test_namespace_suffix; + +/// Enum doc comment. +enum ProtoEnum : int { + NUL = 0, + FOO = 1, + /// Enum 2nd value doc comment misaligned. + BAR = 5, +} + +table ImportedMessage { + a:int; +} + +/// 2nd table doc comment with +/// many lines. +table ProtoMessage { + c:int = 16; + d:long; + p:uint; + e:ulong; + /// doc comment for f. + f:int = -1; + g:long; + h:uint; + q:ulong; + i:int; + j:long; + /// doc comment for k. + k:bool; + /// doc comment for l on 2 + /// lines + l:string (required); + m:[ubyte]; + n:proto.test.test_namespace_suffix.ProtoMessage_.OtherMessage; + o:[string]; + z:proto.test.test_namespace_suffix.ImportedMessage; + /// doc comment for r. + r:proto.test.test_namespace_suffix.ProtoMessage_.Anonymous0; +} + +namespace proto.test.test_namespace_suffix.ProtoMessage_; + +table OtherMessage { + a:double; + /// doc comment for b. + b:float = 3.14149; +} + +table Anonymous0 { + /// doc comment for s. + s:proto.test.test_namespace_suffix.ImportedMessage; + /// doc comment for t on 2 + /// lines. + t:proto.test.test_namespace_suffix.ProtoMessage_.OtherMessage; +} + diff --git a/tests/prototest/test_union_suffix.golden b/tests/prototest/test_union_suffix.golden new file mode 100644 index 0000000..0b0f920 --- /dev/null +++ b/tests/prototest/test_union_suffix.golden @@ -0,0 +1,63 @@ +// Generated from test.proto + +namespace proto.test.test_namespace_suffix; + +/// Enum doc comment. +enum ProtoEnum : int { + NUL = 0, + FOO = 1, + /// Enum 2nd value doc comment misaligned. + BAR = 5, +} + +namespace proto.test.test_namespace_suffix.ProtoMessage_; + +union RUnion { + /// doc comment for s. + proto.test.test_namespace_suffix.ImportedMessage, + /// doc comment for t on 2 + /// lines. + proto.test.test_namespace_suffix.ProtoMessage_.OtherMessage, +} + +namespace proto.test.test_namespace_suffix; + +table ImportedMessage { + a:int; +} + +/// 2nd table doc comment with +/// many lines. +table ProtoMessage { + c:int = 16; + d:long; + p:uint; + e:ulong; + /// doc comment for f. + f:int = -1; + g:long; + h:uint; + q:ulong; + i:int; + j:long; + /// doc comment for k. + k:bool; + /// doc comment for l on 2 + /// lines + l:string (required); + m:[ubyte]; + n:proto.test.test_namespace_suffix.ProtoMessage_.OtherMessage; + o:[string]; + z:proto.test.test_namespace_suffix.ImportedMessage; + /// doc comment for r. + r:proto.test.test_namespace_suffix.ProtoMessage_.RUnion; +} + +namespace proto.test.test_namespace_suffix.ProtoMessage_; + +table OtherMessage { + a:double; + /// doc comment for b. + b:float = 3.14149; +} + diff --git a/tests/test.cpp b/tests/test.cpp index 88a7b8f..c63502b 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -1128,6 +1128,58 @@ void ParseProtoTest() { } // Parse a .proto schema, output as .fbs +void ParseProtoTestWithSuffix() { + // load the .proto and the golden file from disk + std::string protofile; + std::string goldenfile; + std::string goldenunionfile; + TEST_EQ( + flatbuffers::LoadFile((test_data_path + "prototest/test.proto").c_str(), + false, &protofile), + true); + TEST_EQ( + flatbuffers::LoadFile((test_data_path + "prototest/test_suffix.golden").c_str(), + false, &goldenfile), + true); + TEST_EQ(flatbuffers::LoadFile( + (test_data_path + "prototest/test_union_suffix.golden").c_str(), false, + &goldenunionfile), + true); + + flatbuffers::IDLOptions opts; + opts.include_dependence_headers = false; + opts.proto_mode = true; + opts.proto_namespace_suffix = "test_namespace_suffix"; + + // Parse proto. + flatbuffers::Parser parser(opts); + auto protopath = test_data_path + "prototest/"; + const char *include_directories[] = { protopath.c_str(), nullptr }; + TEST_EQ(parser.Parse(protofile.c_str(), include_directories), true); + + // Generate fbs. + auto fbs = flatbuffers::GenerateFBS(parser, "test"); + + // Ensure generated file is parsable. + flatbuffers::Parser parser2; + TEST_EQ(parser2.Parse(fbs.c_str(), nullptr), true); + TEST_EQ_STR(fbs.c_str(), goldenfile.c_str()); + + // Parse proto with --oneof-union option. + opts.proto_oneof_union = true; + flatbuffers::Parser parser3(opts); + TEST_EQ(parser3.Parse(protofile.c_str(), include_directories), true); + + // Generate fbs. + auto fbs_union = flatbuffers::GenerateFBS(parser3, "test"); + + // Ensure generated file is parsable. + flatbuffers::Parser parser4; + TEST_EQ(parser4.Parse(fbs_union.c_str(), nullptr), true); + TEST_EQ_STR(fbs_union.c_str(), goldenunionfile.c_str()); +} + +// Parse a .proto schema, output as .fbs void ParseProtoTestWithIncludes() { // load the .proto and the golden file from disk std::string protofile; @@ -3261,6 +3313,7 @@ int FlatBufferTests() { FixedLengthArrayJsonTest(true); ReflectionTest(flatbuf.data(), flatbuf.size()); ParseProtoTest(); + ParseProtoTestWithSuffix(); ParseProtoTestWithIncludes(); EvolutionTest(); UnionVectorTest();