Generate appropriate schema doc comments from .proto files

- Add parse handling of .proto struct and field doc comments (enums and
their values were already handled)
- Add FBS generation handling of doc comments for structs, their
fields, enums, and their values (requires linking idl_gen_general in
the test binary build)
- Tested using test.proto|golden with doc comments added.  Xcode run of
flattest passes.

Change-Id: Idff64dd8064afba227174ab77d2c7be22d006628
This commit is contained in:
Advay Mengle 2015-03-31 02:03:11 -07:00 committed by Wouter van Oortmerssen
parent b8708beeec
commit 3ad853630c
7 changed files with 32 additions and 1 deletions

View File

@ -40,6 +40,7 @@ set(FlatBuffers_Tests_SRCS
include/flatbuffers/idl.h include/flatbuffers/idl.h
include/flatbuffers/util.h include/flatbuffers/util.h
src/idl_parser.cpp src/idl_parser.cpp
src/idl_gen_general.cpp
src/idl_gen_text.cpp src/idl_gen_text.cpp
src/idl_gen_fbs.cpp src/idl_gen_fbs.cpp
tests/test.cpp tests/test.cpp

View File

@ -268,6 +268,7 @@
<ClInclude Include="..\..\include\flatbuffers\util.h" /> <ClInclude Include="..\..\include\flatbuffers\util.h" />
<ClInclude Include="..\..\tests\monster_test_generated.h" /> <ClInclude Include="..\..\tests\monster_test_generated.h" />
<ClCompile Include="..\..\src\idl_gen_fbs.cpp" /> <ClCompile Include="..\..\src\idl_gen_fbs.cpp" />
<ClCompile Include="..\..\src\idl_gen_general.cpp" />
<ClCompile Include="..\..\src\idl_parser.cpp" /> <ClCompile Include="..\..\src\idl_parser.cpp" />
<ClCompile Include="..\..\src\idl_gen_text.cpp" /> <ClCompile Include="..\..\src\idl_gen_text.cpp" />
<ClCompile Include="..\..\tests\test.cpp" /> <ClCompile Include="..\..\tests\test.cpp" />

View File

@ -8,6 +8,7 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1963D7D2A57344A3B1C1713F /* idl_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3709AC883348409592530AE6 /* idl_parser.cpp */; settings = {COMPILER_FLAGS = ""; }; }; 1963D7D2A57344A3B1C1713F /* idl_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3709AC883348409592530AE6 /* idl_parser.cpp */; settings = {COMPILER_FLAGS = ""; }; };
5AC48C391ACA9A0A008132C5 /* idl_gen_general.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD8717A19CB937D0012A827 /* idl_gen_general.cpp */; };
61823BBC53544106B6DBC38E /* idl_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3709AC883348409592530AE6 /* idl_parser.cpp */; settings = {COMPILER_FLAGS = ""; }; }; 61823BBC53544106B6DBC38E /* idl_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3709AC883348409592530AE6 /* idl_parser.cpp */; settings = {COMPILER_FLAGS = ""; }; };
61FF3C34FBEC4819A1C30F92 /* sample_text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ECCEBFFA6977404F858F9739 /* sample_text.cpp */; settings = {COMPILER_FLAGS = ""; }; }; 61FF3C34FBEC4819A1C30F92 /* sample_text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ECCEBFFA6977404F858F9739 /* sample_text.cpp */; settings = {COMPILER_FLAGS = ""; }; };
8C303C591975D6A700D7C1C5 /* idl_gen_go.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C303C581975D6A700D7C1C5 /* idl_gen_go.cpp */; }; 8C303C591975D6A700D7C1C5 /* idl_gen_go.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C303C581975D6A700D7C1C5 /* idl_gen_go.cpp */; };
@ -344,6 +345,7 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
5AC48C391ACA9A0A008132C5 /* idl_gen_general.cpp in Sources */,
8C6905FD19F835B400CB8866 /* idl_gen_fbs.cpp in Sources */, 8C6905FD19F835B400CB8866 /* idl_gen_fbs.cpp in Sources */,
E0680D6B5BFD484BA9D88EE8 /* idl_gen_text.cpp in Sources */, E0680D6B5BFD484BA9D88EE8 /* idl_gen_text.cpp in Sources */,
61823BBC53544106B6DBC38E /* idl_parser.cpp in Sources */, 61823BBC53544106B6DBC38E /* idl_parser.cpp in Sources */,

View File

@ -61,11 +61,13 @@ std::string GenerateFBS(const Parser &parser, const std::string &file_name,
for (auto enum_def_it = parser.enums_.vec.begin(); for (auto enum_def_it = parser.enums_.vec.begin();
enum_def_it != parser.enums_.vec.end(); ++enum_def_it) { enum_def_it != parser.enums_.vec.end(); ++enum_def_it) {
EnumDef &enum_def = **enum_def_it; EnumDef &enum_def = **enum_def_it;
GenComment(enum_def.doc_comment, &schema, nullptr);
schema += "enum " + enum_def.name + " : "; schema += "enum " + enum_def.name + " : ";
schema += GenType(enum_def.underlying_type) + " {\n"; schema += GenType(enum_def.underlying_type) + " {\n";
for (auto it = enum_def.vals.vec.begin(); for (auto it = enum_def.vals.vec.begin();
it != enum_def.vals.vec.end(); ++it) { it != enum_def.vals.vec.end(); ++it) {
auto &ev = **it; auto &ev = **it;
GenComment(ev.doc_comment, &schema, nullptr, " ");
schema += " " + ev.name + " = " + NumToString(ev.value) + ",\n"; schema += " " + ev.name + " = " + NumToString(ev.value) + ",\n";
} }
schema += "}\n\n"; schema += "}\n\n";
@ -74,10 +76,12 @@ std::string GenerateFBS(const Parser &parser, const std::string &file_name,
for (auto it = parser.structs_.vec.begin(); for (auto it = parser.structs_.vec.begin();
it != parser.structs_.vec.end(); ++it) { it != parser.structs_.vec.end(); ++it) {
StructDef &struct_def = **it; StructDef &struct_def = **it;
GenComment(struct_def.doc_comment, &schema, nullptr);
schema += "table " + struct_def.name + " {\n"; schema += "table " + struct_def.name + " {\n";
for (auto field_it = struct_def.fields.vec.begin(); for (auto field_it = struct_def.fields.vec.begin();
field_it != struct_def.fields.vec.end(); ++field_it) { field_it != struct_def.fields.vec.end(); ++field_it) {
auto &field = **field_it; auto &field = **field_it;
GenComment(field.doc_comment, &schema, nullptr, " ");
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.required) schema += " (required)"; if (field.required) schema += " (required)";

View File

@ -991,10 +991,13 @@ void Parser::ParseProtoDecl() {
// These are identical in syntax to FlatBuffer's namespace decl. // These are identical in syntax to FlatBuffer's namespace decl.
ParseNamespace(); ParseNamespace();
} else if (attribute_ == "message") { } else if (attribute_ == "message") {
std::vector<std::string> struct_comment = doc_comment_;
Next(); Next();
auto &struct_def = StartStruct(); auto &struct_def = StartStruct();
struct_def.doc_comment = struct_comment;
Expect('{'); Expect('{');
while (token_ != '}') { while (token_ != '}') {
std::vector<std::string> field_comment = doc_comment_;
// Parse the qualifier. // Parse the qualifier.
bool required = false; bool required = false;
bool repeated = false; bool repeated = false;
@ -1021,6 +1024,7 @@ void Parser::ParseProtoDecl() {
Expect('='); Expect('=');
Expect(kTokenIntegerConstant); Expect(kTokenIntegerConstant);
auto &field = AddField(struct_def, name, type); auto &field = AddField(struct_def, name, type);
field.doc_comment = field_comment;
field.required = required; field.required = required;
// See if there's a default specified. // See if there's a default specified.
if (IsNext('[')) { if (IsNext('[')) {

View File

@ -2,28 +2,37 @@
namespace proto.test; namespace proto.test;
/// Enum doc comment.
enum ProtoEnum : short { enum ProtoEnum : short {
FOO = 1, FOO = 1,
/// Enum 2nd value doc comment misaligned.
BAR = 5, BAR = 5,
} }
table OtherMessage { table OtherMessage {
a:double; a:double;
/// doc comment for b.
b:float = 3.14149; b:float = 3.14149;
} }
/// 2nd table doc comment with
/// many lines.
table ProtoMessage { table ProtoMessage {
c:int = 16; c:int = 16;
d:long; d:long;
p:uint; p:uint;
e:ulong; e:ulong;
/// doc comment for f.
f:int = -1; f:int = -1;
g:long; g:long;
h:uint; h:uint;
q:ulong; q:ulong;
i:int; i:int;
j:long; j:long;
/// doc comment for k.
k:bool; k:bool;
/// doc comment for l on 2
/// lines
l:string (required); l:string (required);
m:string; m:string;
n:OtherMessage; n:OtherMessage;

View File

@ -5,28 +5,38 @@ package proto.test;
option some_option = is_ignored; option some_option = is_ignored;
import "some_other_schema.proto"; import "some_other_schema.proto";
/// Enum doc comment.
enum ProtoEnum { enum ProtoEnum {
FOO = 1; FOO = 1;
/// Enum 2nd value doc comment misaligned.
BAR = 5; BAR = 5;
} }
// Ignored non-doc comment.
message OtherMessage { message OtherMessage {
optional double a = 26; optional double a = 26;
/// doc comment for b.
optional float b = 32 [default = 3.14149]; optional float b = 32 [default = 3.14149];
} }
/// 2nd table doc comment with
/// many lines.
message ProtoMessage { message ProtoMessage {
optional int32 c = 12 [default = 16]; optional int32 c = 12 [default = 16];
optional int64 d = 1 [default = 0]; optional int64 d = 1 [default = 0];
optional uint32 p = 1; optional uint32 p = 1;
optional uint64 e = 2; optional uint64 e = 2;
/// doc comment for f.
optional sint32 f = 3 [default = -1]; optional sint32 f = 3 [default = -1];
optional sint64 g = 4; optional sint64 g = 4;
optional fixed32 h = 5; optional fixed32 h = 5;
optional fixed64 q = 6; optional fixed64 q = 6;
optional sfixed32 i = 7; optional sfixed32 i = 7;
optional sfixed64 j = 8; optional sfixed64 j = 8;
/// doc comment for k.
optional bool k = 9; optional bool k = 9;
/// doc comment for l on 2
/// lines
required string l = 10; required string l = 10;
optional bytes m = 11; optional bytes m = 11;
optional OtherMessage n = 12; optional OtherMessage n = 12;