diff options
author | Casper <casperneo@uchicago.edu> | 2021-04-27 10:10:59 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-27 10:10:59 -0400 |
commit | 16836ff95a7f112f66a8c5994a508e6bfec010c9 (patch) | |
tree | 9431fa06f6f778cf2e27c41b9021c1114f87fbf3 | |
parent | c87179e73ed568183f8bf94468f5703886e0e6fb (diff) | |
download | flatbuffers-16836ff95a7f112f66a8c5994a508e6bfec010c9.tar.gz flatbuffers-16836ff95a7f112f66a8c5994a508e6bfec010c9.tar.bz2 flatbuffers-16836ff95a7f112f66a8c5994a508e6bfec010c9.zip |
Add advance feature indicators to reflection (#6546)
* Add advance feature indicators to reflection
* deserialize too
* model advanced features as bitflags
* use uint64_t instead of AdvancedFeatures
* git clang format
* initialize advanced_features_
* remove whitespace
Co-authored-by: Casper Neo <cneo@google.com>
-rw-r--r-- | include/flatbuffers/idl.h | 3 | ||||
-rw-r--r-- | include/flatbuffers/reflection_generated.h | 58 | ||||
-rw-r--r-- | reflection/reflection.fbs | 9 | ||||
-rw-r--r-- | src/idl_parser.cpp | 33 | ||||
-rw-r--r-- | tests/arrays_test.bfbs | bin | 1280 -> 1288 bytes |
5 files changed, 88 insertions, 15 deletions
diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 6ae07ab2..29bf6215 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -780,6 +780,7 @@ class Parser : public ParserState { root_struct_def_(nullptr), opts(options), uses_flexbuffers_(false), + advanced_features_(0), source_(nullptr), anonymous_counter_(0), parse_depth_counter_(0) { @@ -1011,6 +1012,8 @@ class Parser : public ParserState { IDLOptions opts; bool uses_flexbuffers_; + uint64_t advanced_features_; + private: const char *source_; diff --git a/include/flatbuffers/reflection_generated.h b/include/flatbuffers/reflection_generated.h index b98afd65..235146e1 100644 --- a/include/flatbuffers/reflection_generated.h +++ b/include/flatbuffers/reflection_generated.h @@ -114,6 +114,44 @@ inline const char *EnumNameBaseType(BaseType e) { return EnumNamesBaseType()[index]; } +enum AdvancedFeatures { + AdvancedArrayFeatures = 1ULL, + AdvancedUnionFeatures = 2ULL, + OptionalScalars = 4ULL, + DefaultVectorsAndStrings = 8ULL +}; + +inline const AdvancedFeatures (&EnumValuesAdvancedFeatures())[4] { + static const AdvancedFeatures values[] = { + AdvancedArrayFeatures, + AdvancedUnionFeatures, + OptionalScalars, + DefaultVectorsAndStrings + }; + return values; +} + +inline const char * const *EnumNamesAdvancedFeatures() { + static const char * const names[9] = { + "AdvancedArrayFeatures", + "AdvancedUnionFeatures", + "", + "OptionalScalars", + "", + "", + "", + "DefaultVectorsAndStrings", + nullptr + }; + return names; +} + +inline const char *EnumNameAdvancedFeatures(AdvancedFeatures e) { + if (flatbuffers::IsOutRange(e, AdvancedArrayFeatures, DefaultVectorsAndStrings)) return ""; + const size_t index = static_cast<size_t>(e) - static_cast<size_t>(AdvancedArrayFeatures); + return EnumNamesAdvancedFeatures()[index]; +} + struct Type FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef TypeBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { @@ -1063,7 +1101,8 @@ struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_FILE_IDENT = 8, VT_FILE_EXT = 10, VT_ROOT_TABLE = 12, - VT_SERVICES = 14 + VT_SERVICES = 14, + VT_ADVANCED_FEATURES = 16 }; const flatbuffers::Vector<flatbuffers::Offset<reflection::Object>> *objects() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Object>> *>(VT_OBJECTS); @@ -1083,6 +1122,9 @@ struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const flatbuffers::Vector<flatbuffers::Offset<reflection::Service>> *services() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Service>> *>(VT_SERVICES); } + reflection::AdvancedFeatures advanced_features() const { + return static_cast<reflection::AdvancedFeatures>(GetField<uint64_t>(VT_ADVANCED_FEATURES, 0)); + } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyOffsetRequired(verifier, VT_OBJECTS) && @@ -1100,6 +1142,7 @@ struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyOffset(verifier, VT_SERVICES) && verifier.VerifyVector(services()) && verifier.VerifyVectorOfTables(services()) && + VerifyField<uint64_t>(verifier, VT_ADVANCED_FEATURES) && verifier.EndTable(); } }; @@ -1126,6 +1169,9 @@ struct SchemaBuilder { void add_services(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Service>>> services) { fbb_.AddOffset(Schema::VT_SERVICES, services); } + void add_advanced_features(reflection::AdvancedFeatures advanced_features) { + fbb_.AddElement<uint64_t>(Schema::VT_ADVANCED_FEATURES, static_cast<uint64_t>(advanced_features), 0); + } explicit SchemaBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); @@ -1146,8 +1192,10 @@ inline flatbuffers::Offset<Schema> CreateSchema( flatbuffers::Offset<flatbuffers::String> file_ident = 0, flatbuffers::Offset<flatbuffers::String> file_ext = 0, flatbuffers::Offset<reflection::Object> root_table = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Service>>> services = 0) { + flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Service>>> services = 0, + reflection::AdvancedFeatures advanced_features = static_cast<reflection::AdvancedFeatures>(0)) { SchemaBuilder builder_(_fbb); + builder_.add_advanced_features(advanced_features); builder_.add_services(services); builder_.add_root_table(root_table); builder_.add_file_ext(file_ext); @@ -1164,7 +1212,8 @@ inline flatbuffers::Offset<Schema> CreateSchemaDirect( const char *file_ident = nullptr, const char *file_ext = nullptr, flatbuffers::Offset<reflection::Object> root_table = 0, - std::vector<flatbuffers::Offset<reflection::Service>> *services = nullptr) { + std::vector<flatbuffers::Offset<reflection::Service>> *services = nullptr, + reflection::AdvancedFeatures advanced_features = static_cast<reflection::AdvancedFeatures>(0)) { auto objects__ = objects ? _fbb.CreateVectorOfSortedTables<reflection::Object>(objects) : 0; auto enums__ = enums ? _fbb.CreateVectorOfSortedTables<reflection::Enum>(enums) : 0; auto file_ident__ = file_ident ? _fbb.CreateString(file_ident) : 0; @@ -1177,7 +1226,8 @@ inline flatbuffers::Offset<Schema> CreateSchemaDirect( file_ident__, file_ext__, root_table, - services__); + services__, + advanced_features); } inline const reflection::Schema *GetSchema(const void *buf) { diff --git a/reflection/reflection.fbs b/reflection/reflection.fbs index d9e2dc47..36230b20 100644 --- a/reflection/reflection.fbs +++ b/reflection/reflection.fbs @@ -102,6 +102,14 @@ table Service { documentation:[string]; } +// New schema language features that are not supported by old code generators. +enum AdvancedFeatures : ulong (bit_flags) { + AdvancedArrayFeatures, + AdvancedUnionFeatures, + OptionalScalars, + DefaultVectorsAndStrings, +} + table Schema { objects:[Object] (required); // Sorted. enums:[Enum] (required); // Sorted. @@ -109,6 +117,7 @@ table Schema { file_ext:string; root_table:Object; services:[Service]; // Sorted. + advanced_features:AdvancedFeatures; } root_type Schema; diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index 88ecf81c..f04e5a3d 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -765,10 +765,13 @@ CheckedError Parser::ParseField(StructDef &struct_def) { if (!struct_def.fixed && IsArray(type)) return Error("fixed-length array in table must be wrapped in struct"); - if (IsArray(type) && !SupportsAdvancedArrayFeatures()) { - return Error( - "Arrays are not yet supported in all " - "the specified programming languages."); + if (IsArray(type)) { + advanced_features_ |= reflection::AdvancedArrayFeatures; + if (!SupportsAdvancedArrayFeatures()) { + return Error( + "Arrays are not yet supported in all " + "the specified programming languages."); + } } FieldDef *typefield = nullptr; @@ -778,6 +781,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) { ECHECK(AddField(struct_def, name + UnionTypeFieldSuffix(), type.enum_def->underlying_type, &typefield)); } else if (IsVector(type) && type.element == BASE_TYPE_UNION) { + advanced_features_ |= reflection::AdvancedUnionFeatures; // Only cpp, js and ts supports the union vector feature so far. if (!SupportsAdvancedUnionFeatures()) { return Error( @@ -802,11 +806,16 @@ CheckedError Parser::ParseField(StructDef &struct_def) { return Error( "default values are not supported for struct fields, table fields, " "or in structs."); - if ((IsString(type) || IsVector(type)) && field->value.constant != "0" && - field->value.constant != "null" && !SupportsDefaultVectorsAndStrings()) - return Error( - "Default values for strings and vectors are not supported in one of " - "the specified programming languages"); + if (IsString(type) || IsVector(type)) { + advanced_features_ |= reflection::DefaultVectorsAndStrings; + if (field->value.constant != "0" && field->value.constant != "null" && + !SupportsDefaultVectorsAndStrings()) { + return Error( + "Default values for strings and vectors are not supported in one " + "of the specified programming languages"); + } + } + if (IsVector(type) && field->value.constant != "0" && field->value.constant != "[]") { return Error("The only supported default for vectors is `[]`."); @@ -891,6 +900,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) { } if (field->IsScalarOptional()) { + advanced_features_ |= reflection::OptionalScalars; if (type.enum_def && type.enum_def->Lookup("null")) { FLATBUFFERS_ASSERT(IsInteger(type.base_type)); return Error( @@ -3498,7 +3508,8 @@ void Parser::Serialize() { auto serv__ = builder_.CreateVectorOfSortedTables(&service_offsets); auto schema_offset = reflection::CreateSchema( builder_, objs__, enum__, fiid__, fext__, - (root_struct_def_ ? root_struct_def_->serialized_location : 0), serv__); + (root_struct_def_ ? root_struct_def_->serialized_location : 0), serv__, + static_cast<reflection::AdvancedFeatures>(advanced_features_)); if (opts.size_prefixed) { builder_.FinishSizePrefixed(schema_offset, reflection::SchemaIdentifier()); } else { @@ -3915,7 +3926,7 @@ bool Parser::Deserialize(const reflection::Schema *schema) { } } } - + advanced_features_ = schema->advanced_features(); return true; } diff --git a/tests/arrays_test.bfbs b/tests/arrays_test.bfbs Binary files differindex fe24507f..d6b6f731 100644 --- a/tests/arrays_test.bfbs +++ b/tests/arrays_test.bfbs |