From: Casper Date: Tue, 27 Apr 2021 14:10:59 +0000 (-0400) Subject: Add advance feature indicators to reflection (#6546) X-Git-Tag: v2.0.0~21 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=16836ff95a7f112f66a8c5994a508e6bfec010c9;p=platform%2Fupstream%2Fflatbuffers.git 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 --- diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 6ae07ab..29bf621 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 b98afd6..235146e 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(e) - static_cast(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> *objects() const { return GetPointer> *>(VT_OBJECTS); @@ -1083,6 +1122,9 @@ struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const flatbuffers::Vector> *services() const { return GetPointer> *>(VT_SERVICES); } + reflection::AdvancedFeatures advanced_features() const { + return static_cast(GetField(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(verifier, VT_ADVANCED_FEATURES) && verifier.EndTable(); } }; @@ -1126,6 +1169,9 @@ struct SchemaBuilder { void add_services(flatbuffers::Offset>> services) { fbb_.AddOffset(Schema::VT_SERVICES, services); } + void add_advanced_features(reflection::AdvancedFeatures advanced_features) { + fbb_.AddElement(Schema::VT_ADVANCED_FEATURES, static_cast(advanced_features), 0); + } explicit SchemaBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); @@ -1146,8 +1192,10 @@ inline flatbuffers::Offset CreateSchema( flatbuffers::Offset file_ident = 0, flatbuffers::Offset file_ext = 0, flatbuffers::Offset root_table = 0, - flatbuffers::Offset>> services = 0) { + flatbuffers::Offset>> services = 0, + reflection::AdvancedFeatures advanced_features = static_cast(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 CreateSchemaDirect( const char *file_ident = nullptr, const char *file_ext = nullptr, flatbuffers::Offset root_table = 0, - std::vector> *services = nullptr) { + std::vector> *services = nullptr, + reflection::AdvancedFeatures advanced_features = static_cast(0)) { auto objects__ = objects ? _fbb.CreateVectorOfSortedTables(objects) : 0; auto enums__ = enums ? _fbb.CreateVectorOfSortedTables(enums) : 0; auto file_ident__ = file_ident ? _fbb.CreateString(file_ident) : 0; @@ -1177,7 +1226,8 @@ inline flatbuffers::Offset 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 d9e2dc4..36230b2 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 88ecf81..f04e5a3 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(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 index fe24507..d6b6f73 100644 Binary files a/tests/arrays_test.bfbs and b/tests/arrays_test.bfbs differ