From 1fb6b9ee6f817befae08f39549d5bd80de3931cc Mon Sep 17 00:00:00 2001 From: Wouter van Oortmerssen Date: Mon, 13 Feb 2017 16:15:55 -0800 Subject: [PATCH] Added doc comments to the binary schema. Change-Id: I87f291ab6e07b1425850cae25ed500db594f17c8 Tested: on Linux. --- docs/source/Compiler.md | 2 + include/flatbuffers/idl.h | 2 + include/flatbuffers/reflection_generated.h | 72 ++++++++++++++++----- reflection/reflection.fbs | 3 + src/flatc.cpp | 3 + src/idl_parser.cpp | 16 ++++- tests/generate_code.sh | 1 + tests/monster_test.bfbs | Bin 3320 -> 3904 bytes 8 files changed, 81 insertions(+), 18 deletions(-) diff --git a/docs/source/Compiler.md b/docs/source/Compiler.md index 6d881cc8f..a155df468 100755 --- a/docs/source/Compiler.md +++ b/docs/source/Compiler.md @@ -114,6 +114,8 @@ Additional options: to the reflection/reflection.fbs schema. Loading this binary file is the basis for reflection functionality. +- `--bfbs-comments`: Add doc comments to the binary schema files. + - `--conform FILE` : Specify a schema the following schemas should be an evolution of. Gives errors if not. Useful to check if schema modifications don't break schema evolution rules. diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 2e09b39a5..5b7a72a3c 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -356,6 +356,7 @@ struct IDLOptions { bool union_value_namespacing; bool allow_non_utf8; std::string include_prefix; + bool binary_schema_comments; // Possible options for the more general generator below. enum Language { @@ -396,6 +397,7 @@ struct IDLOptions { cpp_object_api_pointer_type("std::unique_ptr"), union_value_namespacing(true), allow_non_utf8(false), + binary_schema_comments(false), lang(IDLOptions::kJava), lang_to_generate(0) {} }; diff --git a/include/flatbuffers/reflection_generated.h b/include/flatbuffers/reflection_generated.h index df745f231..8379dcf52 100644 --- a/include/flatbuffers/reflection_generated.h +++ b/include/flatbuffers/reflection_generated.h @@ -294,7 +294,8 @@ struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_VALUES = 6, VT_IS_UNION = 8, VT_UNDERLYING_TYPE = 10, - VT_ATTRIBUTES = 12 + VT_ATTRIBUTES = 12, + VT_DOCUMENTATION = 14 }; const flatbuffers::String *name() const { return GetPointer(VT_NAME); @@ -317,6 +318,9 @@ struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const flatbuffers::Vector> *attributes() const { return GetPointer> *>(VT_ATTRIBUTES); } + const flatbuffers::Vector> *documentation() const { + return GetPointer> *>(VT_DOCUMENTATION); + } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyFieldRequired(verifier, VT_NAME) && @@ -330,6 +334,9 @@ struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyField(verifier, VT_ATTRIBUTES) && verifier.Verify(attributes()) && verifier.VerifyVectorOfTables(attributes()) && + VerifyField(verifier, VT_DOCUMENTATION) && + verifier.Verify(documentation()) && + verifier.VerifyVectorOfStrings(documentation()) && verifier.EndTable(); } }; @@ -352,13 +359,16 @@ struct EnumBuilder { void add_attributes(flatbuffers::Offset>> attributes) { fbb_.AddOffset(Enum::VT_ATTRIBUTES, attributes); } + void add_documentation(flatbuffers::Offset>> documentation) { + fbb_.AddOffset(Enum::VT_DOCUMENTATION, documentation); + } EnumBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } EnumBuilder &operator=(const EnumBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 5); + const auto end = fbb_.EndTable(start_, 6); auto o = flatbuffers::Offset(end); fbb_.Required(o, Enum::VT_NAME); fbb_.Required(o, Enum::VT_VALUES); @@ -373,8 +383,10 @@ inline flatbuffers::Offset CreateEnum( flatbuffers::Offset>> values = 0, bool is_union = false, flatbuffers::Offset underlying_type = 0, - flatbuffers::Offset>> attributes = 0) { + flatbuffers::Offset>> attributes = 0, + flatbuffers::Offset>> documentation = 0) { EnumBuilder builder_(_fbb); + builder_.add_documentation(documentation); builder_.add_attributes(attributes); builder_.add_underlying_type(underlying_type); builder_.add_values(values); @@ -389,14 +401,16 @@ inline flatbuffers::Offset CreateEnumDirect( const std::vector> *values = nullptr, bool is_union = false, flatbuffers::Offset underlying_type = 0, - const std::vector> *attributes = nullptr) { + const std::vector> *attributes = nullptr, + const std::vector> *documentation = nullptr) { return reflection::CreateEnum( _fbb, name ? _fbb.CreateString(name) : 0, values ? _fbb.CreateVector>(*values) : 0, is_union, underlying_type, - attributes ? _fbb.CreateVector>(*attributes) : 0); + attributes ? _fbb.CreateVector>(*attributes) : 0, + documentation ? _fbb.CreateVector>(*documentation) : 0); } struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { @@ -410,7 +424,8 @@ struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_DEPRECATED = 16, VT_REQUIRED = 18, VT_KEY = 20, - VT_ATTRIBUTES = 22 + VT_ATTRIBUTES = 22, + VT_DOCUMENTATION = 24 }; const flatbuffers::String *name() const { return GetPointer(VT_NAME); @@ -448,6 +463,9 @@ struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const flatbuffers::Vector> *attributes() const { return GetPointer> *>(VT_ATTRIBUTES); } + const flatbuffers::Vector> *documentation() const { + return GetPointer> *>(VT_DOCUMENTATION); + } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyFieldRequired(verifier, VT_NAME) && @@ -464,6 +482,9 @@ struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyField(verifier, VT_ATTRIBUTES) && verifier.Verify(attributes()) && verifier.VerifyVectorOfTables(attributes()) && + VerifyField(verifier, VT_DOCUMENTATION) && + verifier.Verify(documentation()) && + verifier.VerifyVectorOfStrings(documentation()) && verifier.EndTable(); } }; @@ -501,13 +522,16 @@ struct FieldBuilder { void add_attributes(flatbuffers::Offset>> attributes) { fbb_.AddOffset(Field::VT_ATTRIBUTES, attributes); } + void add_documentation(flatbuffers::Offset>> documentation) { + fbb_.AddOffset(Field::VT_DOCUMENTATION, documentation); + } FieldBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } FieldBuilder &operator=(const FieldBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 10); + const auto end = fbb_.EndTable(start_, 11); auto o = flatbuffers::Offset(end); fbb_.Required(o, Field::VT_NAME); fbb_.Required(o, Field::VT_TYPE); @@ -526,10 +550,12 @@ inline flatbuffers::Offset CreateField( bool deprecated = false, bool required = false, bool key = false, - flatbuffers::Offset>> attributes = 0) { + flatbuffers::Offset>> attributes = 0, + flatbuffers::Offset>> documentation = 0) { FieldBuilder builder_(_fbb); builder_.add_default_real(default_real); builder_.add_default_integer(default_integer); + builder_.add_documentation(documentation); builder_.add_attributes(attributes); builder_.add_type(type); builder_.add_name(name); @@ -552,7 +578,8 @@ inline flatbuffers::Offset CreateFieldDirect( bool deprecated = false, bool required = false, bool key = false, - const std::vector> *attributes = nullptr) { + const std::vector> *attributes = nullptr, + const std::vector> *documentation = nullptr) { return reflection::CreateField( _fbb, name ? _fbb.CreateString(name) : 0, @@ -564,7 +591,8 @@ inline flatbuffers::Offset CreateFieldDirect( deprecated, required, key, - attributes ? _fbb.CreateVector>(*attributes) : 0); + attributes ? _fbb.CreateVector>(*attributes) : 0, + documentation ? _fbb.CreateVector>(*documentation) : 0); } struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { @@ -574,7 +602,8 @@ struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_IS_STRUCT = 8, VT_MINALIGN = 10, VT_BYTESIZE = 12, - VT_ATTRIBUTES = 14 + VT_ATTRIBUTES = 14, + VT_DOCUMENTATION = 16 }; const flatbuffers::String *name() const { return GetPointer(VT_NAME); @@ -600,6 +629,9 @@ struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const flatbuffers::Vector> *attributes() const { return GetPointer> *>(VT_ATTRIBUTES); } + const flatbuffers::Vector> *documentation() const { + return GetPointer> *>(VT_DOCUMENTATION); + } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyFieldRequired(verifier, VT_NAME) && @@ -613,6 +645,9 @@ struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyField(verifier, VT_ATTRIBUTES) && verifier.Verify(attributes()) && verifier.VerifyVectorOfTables(attributes()) && + VerifyField(verifier, VT_DOCUMENTATION) && + verifier.Verify(documentation()) && + verifier.VerifyVectorOfStrings(documentation()) && verifier.EndTable(); } }; @@ -638,13 +673,16 @@ struct ObjectBuilder { void add_attributes(flatbuffers::Offset>> attributes) { fbb_.AddOffset(Object::VT_ATTRIBUTES, attributes); } + void add_documentation(flatbuffers::Offset>> documentation) { + fbb_.AddOffset(Object::VT_DOCUMENTATION, documentation); + } ObjectBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } ObjectBuilder &operator=(const ObjectBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 6); + const auto end = fbb_.EndTable(start_, 7); auto o = flatbuffers::Offset(end); fbb_.Required(o, Object::VT_NAME); fbb_.Required(o, Object::VT_FIELDS); @@ -659,8 +697,10 @@ inline flatbuffers::Offset CreateObject( bool is_struct = false, int32_t minalign = 0, int32_t bytesize = 0, - flatbuffers::Offset>> attributes = 0) { + flatbuffers::Offset>> attributes = 0, + flatbuffers::Offset>> documentation = 0) { ObjectBuilder builder_(_fbb); + builder_.add_documentation(documentation); builder_.add_attributes(attributes); builder_.add_bytesize(bytesize); builder_.add_minalign(minalign); @@ -677,7 +717,8 @@ inline flatbuffers::Offset CreateObjectDirect( bool is_struct = false, int32_t minalign = 0, int32_t bytesize = 0, - const std::vector> *attributes = nullptr) { + const std::vector> *attributes = nullptr, + const std::vector> *documentation = nullptr) { return reflection::CreateObject( _fbb, name ? _fbb.CreateString(name) : 0, @@ -685,7 +726,8 @@ inline flatbuffers::Offset CreateObjectDirect( is_struct, minalign, bytesize, - attributes ? _fbb.CreateVector>(*attributes) : 0); + attributes ? _fbb.CreateVector>(*attributes) : 0, + documentation ? _fbb.CreateVector>(*documentation) : 0); } struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { diff --git a/reflection/reflection.fbs b/reflection/reflection.fbs index 57f234c6a..76ccf85cc 100644 --- a/reflection/reflection.fbs +++ b/reflection/reflection.fbs @@ -51,6 +51,7 @@ table Enum { is_union:bool = false; underlying_type:Type (required); attributes:[KeyValue]; + documentation:[string]; } table Field { @@ -64,6 +65,7 @@ table Field { required:bool = false; key:bool = false; attributes:[KeyValue]; + documentation:[string]; } table Object { // Used for both tables and structs. @@ -73,6 +75,7 @@ table Object { // Used for both tables and structs. minalign:int; bytesize:int; // For structs. attributes:[KeyValue]; + documentation:[string]; } table Schema { diff --git a/src/flatc.cpp b/src/flatc.cpp index 053f112b1..ed13c2ad5 100644 --- a/src/flatc.cpp +++ b/src/flatc.cpp @@ -93,6 +93,7 @@ std::string FlatCompiler::GetUsageString(const char* program_name) const { " --proto Input is a .proto, translate to .fbs.\n" " --grpc Generate GRPC interfaces for the specified languages\n" " --schema Serialize schemas instead of JSON (use with -b)\n" + " --bfbs-comments Add doc comments to the binary schema files.\n" " --conform FILE Specify a schema the following schemas should be\n" " an evolution of. Gives errors if not.\n" " --conform-includes Include path for the schema given with --conform\n" @@ -204,6 +205,8 @@ int FlatCompiler::Compile(int argc, const char** argv) { exit(0); } else if(arg == "--grpc") { grpc_enabled = true; + } else if(arg == "--bfbs-comments") { + opts.binary_schema_comments = true; } else { for (size_t i = 0; i < params_.num_generators; ++i) { if (arg == params_.generators[i].generator_opt_long || diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index 454abd308..7adfcca24 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -2086,7 +2086,11 @@ Offset StructDef::Serialize(FlatBufferBuilder *builder, fixed, static_cast(minalign), static_cast(bytesize), - SerializeAttributes(builder, parser)); + SerializeAttributes(builder, parser), + parser.opts.binary_schema_comments + ? builder->CreateVectorOfStrings( + doc_comment) + : 0); } Offset FieldDef::Serialize(FlatBufferBuilder *builder, @@ -2106,7 +2110,10 @@ Offset FieldDef::Serialize(FlatBufferBuilder *builder, deprecated, required, key, - SerializeAttributes(builder, parser)); + SerializeAttributes(builder, parser), + parser.opts.binary_schema_comments + ? builder->CreateVectorOfStrings(doc_comment) + : 0); // TODO: value.constant is almost always "0", we could save quite a bit of // space by sharing it. Same for common values of value.type. } @@ -2123,7 +2130,10 @@ Offset EnumDef::Serialize(FlatBufferBuilder *builder, builder->CreateVector(enumval_offsets), is_union, underlying_type.Serialize(builder), - SerializeAttributes(builder, parser)); + SerializeAttributes(builder, parser), + parser.opts.binary_schema_comments + ? builder->CreateVectorOfStrings(doc_comment) + : 0); } Offset EnumVal::Serialize(FlatBufferBuilder *builder) const diff --git a/tests/generate_code.sh b/tests/generate_code.sh index 0510b01d2..a5354ebce 100755 --- a/tests/generate_code.sh +++ b/tests/generate_code.sh @@ -17,6 +17,7 @@ ../flatc --cpp --java --csharp --go --binary --python --js --php --grpc --gen-mutable --gen-object-api --no-includes monster_test.fbs monsterdata_test.json ../flatc --cpp --java --csharp --go --binary --python --js --php --gen-mutable -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs ../flatc --cpp -o union_vector ./union_vector/union_vector.fbs +../flatc -b --schema --bfbs-comments monster_test.fbs cd ../samples ../flatc --cpp --gen-mutable --gen-object-api monster.fbs cd ../reflection diff --git a/tests/monster_test.bfbs b/tests/monster_test.bfbs index 41d9edb1c43c2965eddd178a73fa1c7c08409a7c..21f3c0008fc9a5632ea6aa2c6667f93251da08eb 100644 GIT binary patch literal 3904 zcmai1-D_M$6hE7!`RX=F)7Zu|%54cDl(4j$5K0k=(S8Uv6;opoG2HCl?XKLtciFvL zn<64oiWKRClu|^bi1bOsr#|#Siin6v@ehzv`Xog}@T;ww_4hk-XLGY8IB<4m?wsHG znsa7mM@3}r$lL-tv_2V@4(XP(49E~>f?tvSpr=63fv&ZQbfLeB{?lHO_qU0Bn--~T z70Cne8K@oW#7w6|9)LP9K7L|eb#Sd529Q6jdb%*87XG58*pGpxLDV@2I=*t$Eqj^6 zXWeqe_cG4}D@NumtbGJJ1)`mq-x>{c&}iCsjYfmtzlV*~YuhdijLfB2W_Ia#7}O%K zij`iCK^oS zR@d#-MuV{-&7YV*j82ZhW@08lHU{*eB?ixien?~0FCYCZhVW2j;lp+}{b5{R^72@x*ObK70hL90^x+_A7PJQx z`*9*FdewRC>O#fMd6^^Cu>5?G^XqvSrLrCLtHzg}HJf^&fz}&4IHKJ#a?wQ~=)a90 zV{jF;6Vwtvy9M$D*6za5{Sa2{6dA<^rP1fn-$j2J{cBivK<7af2>lVf?*KQ6{uBam z9yEsUKj7OnP#W_I7=0P^1-^fc{x13#&==9ahjn!7$pQ3^8#taxZYLk+>SZs8+^7@= zPA)8Sa>zl+Fg=}c`3)}@0dxJ2Mq?Be!e~37F%WAdLSDMns=E>vYEiWmoX(1T@`yRn zhbj=c1Ke&oq&ViwFbHlct}rEX5$l*D<3(6MBiKFije;DIY2C9;4CH^Az=({1mnTSv z$|csc0j!8TE;H-o1s8Vz`fyLrEJAB+K;QT0nhlpQ9!3@={p9{8{9F!0zlKk8@o)7L zQ5N|IxLuN6hue6O%%#MKhG8wS@y+{|B% z#$%G%6jz_hHue2ta9WZ9a6>Y=DXx~lje{4ec!bDxjCaVsbvPTBq<`dn-Qd)}I~Wh* zbV>S`#99A{yJB$a-_8e(#&#Ls6leV-?zX|HfAhc%AUikJ7yCzCCwS4Re-|+Bm%WN( zjxzr!ko(6C$53VrzwY-9jQfzG)I)v;M8nDNl`9dh44HqZ^7~U5v)u<~n>?u)*3Sfp z`ASScT)yDD(Q>^|(2GIt|Eu|hsuvlDtTe2mK3gBmVK4B?)O9n~g`u`Z%(tQfY#gY| z=2cv;5ib%Zat3vWD(EMW&e3-&<$dgw>wZ-7OM&M^VTiMj-~Rvnh>E3}^JdBS9WTf` z^@>vp92~*UY1mtJ;VF(9J$qMSCvQM&C*#s$r#V;f{Sodjd#=pjjOoEiOC0Sb&erra zPU$pGgD&i#CLw&&O#@E=TsI<^j3a&J9-xypt!ceZIF*mV--VNo{H^=E6s=S|e4jBG zyUp@0?CgXH%g@*|mu#b*x%fh@8f^3a?8AHuBA<*0^Qsh_!ND9>SKv{%`eyDT#DnIe z@f_qk%KEHn4Nr&l90Ws(uLRbfJzHPIn06JaCG3*VG?EcxPaB<~4d!I+RzC7F_t;me zrLbDkG#Bz70GT$TySZiu&wJW36x)$Xwd?*ES&R`K2yizO|Dn;ZcL(o-HfSS{wK-3w zxN%R571Y1MFsx`J;>1>Ws@s@VQFa5DpZ5NvwW~6p*7{)d z%$tRHT&YqCYm(I(m40H`=73|2DVuSb1nmH|yayI=;i?Ssz6F{FvGqY7eWotPnz~HB z)B`5yO=B0YLpcOq`eW@PKkYh$hsiy|r)Mc+G8D^HAi>&9Oz3%12IE@F>0Ydw zaf&)7K(yNd9RzLQ-=deBf@Q|HW9W(d8FUMD8N~JoGPl4s>nrz|zOojl&|lJemuBtm z!@NVY%g9Ue<5?hI8vbT2y^47|EVc4&EGeJ)+G+T?EEh1gai?#zm-}}PlrenzM)@4$ zR7l#r#}?C%~BNj3H&P9|yJM%1M~J;nSZO=9y_W?^$oO-nO+p zrvKc#{UCcDlFQ^5ANV{sS*!L8k!CFU+B5Gg{)3|YVSWE$(98+SWF1h)201}LRIiWq zq}?Vr&HD{YakKT>wk|j6^D^iwtw~LH%tm07`8N=Q<1Vc=&wZfp%opNaJwwg;Xzm9M z0aga#+1kGf?jGN`+#~vAFUovdT?kCPciS!nv7lY2mUlOWo) P@&A;UgL(~rb`tGBDj=Xf literal 3320 zcmZu!O=w(I6h4zoGCxTsX&c+IjU_Fm1PMbr386@k7@HQsB+$f|RnwQu8)snV%`o#O zG$P_cN>)W&gecy;Z_>Gw3~49NJt;OE@R zJSw=aNB#BTFO zd&fa7d9!Jk*C5-15g$!)2)>8F?}7gUo&ybbgYf(u@(J)k82l3ZY3Sv^_u$ks&?7v5 z0$Kr;@q7=sDEKAtG4KNTJ}3VO{@-uk9oK<+v6zZ{FEEI8HXxt4K?BzCw1(iKkH`L$JIR&HQV=~--Ss@EOlrtzZoiO2FM`56W= zSI0mt-=Ia`@zwW}IQl#S`V=-83v);xb=_;8kNun4e)k=4`b!LTdHx1IeAl!*mQ?kn zgj2t6-c|QfLOk~zhXReW!}+|2X#5vc~m30Jphg^vwH*pbahW zc@7>zMQz?FXH)BWBt83(H_I5uH%9jkIBiaVsCORJQqLv0-S%f7@w`j6|5z91#4cMG z_8;@ky4cmY_nbq#E%xT>`#)gr1b;D8-`K6!kha30HZ`Qb>Z}#WwSSxo_V)l@nnnLY z>W1llV?1l1$LbzPCnt)|s!=eEddw&NqK>2Px1Kn9mP*$EJZ@A(`_DWx57cS=KDWR3 l)2aH8H^><^eb)amG~%a?QDcL#wg2t;o>!}?AFn`&{0H?cVo(48