From: Liu Liu Date: Tue, 16 Jun 2020 06:18:12 +0000 (-0700) Subject: [idl_parser] Mark typefield as deprecated (#5958) X-Git-Tag: v2.0.0~302 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cc44a4442716601600aa50fb8a42abd55294212c;p=platform%2Fupstream%2Fflatbuffers.git [idl_parser] Mark typefield as deprecated (#5958) * Mark typefield as deprecated * Add UnionDeprecation Test. * Update to use evolution schema instead. * Use --scoped-enums to compile. --- diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index af74610..611f28d 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -878,6 +878,11 @@ CheckedError Parser::ParseField(StructDef &struct_def) { val->constant = NumToString(id - 1); typefield->attributes.Add("id", val); } + // if this field is a union that is deprecated, + // the automatically added type field should be deprecated as well + if (field->deprecated) { + typefield->deprecated = true; + } } EXPECT(';'); diff --git a/tests/evolution_test/evolution_v1.fbs b/tests/evolution_test/evolution_v1.fbs index 2576c87..e9d3b8d 100644 --- a/tests/evolution_test/evolution_v1.fbs +++ b/tests/evolution_test/evolution_v1.fbs @@ -34,6 +34,7 @@ table Root { g:[int]; h:[TableB]; i:int = 1234; + j:Union; } -root_type Root; \ No newline at end of file +root_type Root; diff --git a/tests/evolution_test/evolution_v1.json b/tests/evolution_test/evolution_v1.json index 8b4b352..c90fdb9 100644 --- a/tests/evolution_test/evolution_v1.json +++ b/tests/evolution_test/evolution_v1.json @@ -22,5 +22,8 @@ { "a": 459 } - ] -} \ No newline at end of file + ], + "j": { + "a": 984 + } +} diff --git a/tests/evolution_test/evolution_v1_generated.h b/tests/evolution_test/evolution_v1_generated.h index 25afa69..584dfe4 100644 --- a/tests/evolution_test/evolution_v1_generated.h +++ b/tests/evolution_test/evolution_v1_generated.h @@ -10,12 +10,15 @@ namespace Evolution { namespace V1 { struct TableA; +struct TableABuilder; struct TableB; +struct TableBBuilder; struct Struct; struct Root; +struct RootBuilder; enum class Enum : int8_t { King = 0, @@ -42,7 +45,7 @@ inline const char * const *EnumNamesEnum() { } inline const char *EnumNameEnum(Enum e) { - if (e < Enum::King || e > Enum::Queen) return ""; + if (flatbuffers::IsOutRange(e, Enum::King, Enum::Queen)) return ""; const size_t index = static_cast(e); return EnumNamesEnum()[index]; } @@ -75,7 +78,7 @@ inline const char * const *EnumNamesUnion() { } inline const char *EnumNameUnion(Union e) { - if (e < Union::NONE || e > Union::TableB) return ""; + if (flatbuffers::IsOutRange(e, Union::NONE, Union::TableB)) return ""; const size_t index = static_cast(e); return EnumNamesUnion()[index]; } @@ -102,14 +105,16 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Struct FLATBUFFERS_FINAL_CLASS { double b_; public: - Struct() { - memset(static_cast(this), 0, sizeof(Struct)); + Struct() + : a_(0), + padding0__(0), + b_(0) { + (void)padding0__; } Struct(int32_t _a, double _b) : a_(flatbuffers::EndianScalar(_a)), padding0__(0), b_(flatbuffers::EndianScalar(_b)) { - (void)padding0__; } int32_t a() const { return flatbuffers::EndianScalar(a_); @@ -121,6 +126,7 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Struct FLATBUFFERS_FINAL_CLASS { FLATBUFFERS_STRUCT_END(Struct, 16); struct TableA FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef TableABuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_A = 4, VT_B = 6 @@ -140,6 +146,7 @@ struct TableA FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { }; struct TableABuilder { + typedef TableA Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; void add_a(float a) { @@ -170,6 +177,7 @@ inline flatbuffers::Offset CreateTableA( } struct TableB FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef TableBBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_A = 4 }; @@ -184,6 +192,7 @@ struct TableB FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { }; struct TableBBuilder { + typedef TableB Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; void add_a(int32_t a) { @@ -209,6 +218,7 @@ inline flatbuffers::Offset CreateTableB( } struct Root FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef RootBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_A = 4, VT_B = 6, @@ -219,7 +229,9 @@ struct Root FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_F = 16, VT_G = 18, VT_H = 20, - VT_I = 22 + VT_I = 22, + VT_J_TYPE = 24, + VT_J = 26 }; int32_t a() const { return GetField(VT_A, 0); @@ -258,6 +270,19 @@ struct Root FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { int32_t i() const { return GetField(VT_I, 1234); } + Evolution::V1::Union j_type() const { + return static_cast(GetField(VT_J_TYPE, 0)); + } + const void *j() const { + return GetPointer(VT_J); + } + template const T *j_as() const; + const Evolution::V1::TableA *j_as_TableA() const { + return j_type() == Evolution::V1::Union::TableA ? static_cast(j()) : nullptr; + } + const Evolution::V1::TableB *j_as_TableB() const { + return j_type() == Evolution::V1::Union::TableB ? static_cast(j()) : nullptr; + } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_A) && @@ -275,6 +300,9 @@ struct Root FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { verifier.VerifyVector(h()) && verifier.VerifyVectorOfTables(h()) && VerifyField(verifier, VT_I) && + VerifyField(verifier, VT_J_TYPE) && + VerifyOffset(verifier, VT_J) && + VerifyUnion(verifier, j(), j_type()) && verifier.EndTable(); } }; @@ -287,7 +315,16 @@ template<> inline const Evolution::V1::TableB *Root::c_as return c_as_TableB(); } +template<> inline const Evolution::V1::TableA *Root::j_as() const { + return j_as_TableA(); +} + +template<> inline const Evolution::V1::TableB *Root::j_as() const { + return j_as_TableB(); +} + struct RootBuilder { + typedef Root Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; void add_a(int32_t a) { @@ -320,6 +357,12 @@ struct RootBuilder { void add_i(int32_t i) { fbb_.AddElement(Root::VT_I, i, 1234); } + void add_j_type(Evolution::V1::Union j_type) { + fbb_.AddElement(Root::VT_J_TYPE, static_cast(j_type), 0); + } + void add_j(flatbuffers::Offset j) { + fbb_.AddOffset(Root::VT_J, j); + } explicit RootBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); @@ -342,8 +385,11 @@ inline flatbuffers::Offset CreateRoot( const Evolution::V1::Struct *f = 0, flatbuffers::Offset> g = 0, flatbuffers::Offset>> h = 0, - int32_t i = 1234) { + int32_t i = 1234, + Evolution::V1::Union j_type = Evolution::V1::Union::NONE, + flatbuffers::Offset j = 0) { RootBuilder builder_(_fbb); + builder_.add_j(j); builder_.add_i(i); builder_.add_h(h); builder_.add_g(g); @@ -351,6 +397,7 @@ inline flatbuffers::Offset CreateRoot( builder_.add_e(e); builder_.add_c(c); builder_.add_a(a); + builder_.add_j_type(j_type); builder_.add_d(d); builder_.add_c_type(c_type); builder_.add_b(b); @@ -368,7 +415,9 @@ inline flatbuffers::Offset CreateRootDirect( const Evolution::V1::Struct *f = 0, const std::vector *g = nullptr, const std::vector> *h = nullptr, - int32_t i = 1234) { + int32_t i = 1234, + Evolution::V1::Union j_type = Evolution::V1::Union::NONE, + flatbuffers::Offset j = 0) { auto g__ = g ? _fbb.CreateVector(*g) : 0; auto h__ = h ? _fbb.CreateVector>(*h) : 0; return Evolution::V1::CreateRoot( @@ -382,7 +431,9 @@ inline flatbuffers::Offset CreateRootDirect( f, g__, h__, - i); + i, + j_type, + j); } inline bool VerifyUnion(flatbuffers::Verifier &verifier, const void *obj, Union type) { diff --git a/tests/evolution_test/evolution_v2.fbs b/tests/evolution_test/evolution_v2.fbs index 5f4601e..c7e1ef9 100644 --- a/tests/evolution_test/evolution_v2.fbs +++ b/tests/evolution_test/evolution_v2.fbs @@ -43,8 +43,9 @@ table Root { g:[int]; h:[TableB]; i:uint = 1234; - j:TableC; // new in v2 - k:uint8 = 56; // new in v2 + j:Union (deprecated); // deprecated in v2 + k:TableC; // new in v2 + l:uint8 = 56; // new in v2 } -root_type Root; \ No newline at end of file +root_type Root; diff --git a/tests/evolution_test/evolution_v2.json b/tests/evolution_test/evolution_v2.json index 625f506..b170eb2 100644 --- a/tests/evolution_test/evolution_v2.json +++ b/tests/evolution_test/evolution_v2.json @@ -27,7 +27,7 @@ } ], "i": 4321, - "j": { + "k": { "a": 9874.342, "b": "more please" } diff --git a/tests/evolution_test/evolution_v2_generated.h b/tests/evolution_test/evolution_v2_generated.h index 446d9e2..07adec5 100644 --- a/tests/evolution_test/evolution_v2_generated.h +++ b/tests/evolution_test/evolution_v2_generated.h @@ -10,14 +10,18 @@ namespace Evolution { namespace V2 { struct TableA; +struct TableABuilder; struct TableB; +struct TableBBuilder; struct TableC; +struct TableCBuilder; struct Struct; struct Root; +struct RootBuilder; enum class Enum : int8_t { King = 0, @@ -50,7 +54,7 @@ inline const char * const *EnumNamesEnum() { } inline const char *EnumNameEnum(Enum e) { - if (e < Enum::King || e > Enum::Bishop) return ""; + if (flatbuffers::IsOutRange(e, Enum::King, Enum::Bishop)) return ""; const size_t index = static_cast(e); return EnumNamesEnum()[index]; } @@ -86,7 +90,7 @@ inline const char * const *EnumNamesUnion() { } inline const char *EnumNameUnion(Union e) { - if (e < Union::NONE || e > Union::TableC) return ""; + if (flatbuffers::IsOutRange(e, Union::NONE, Union::TableC)) return ""; const size_t index = static_cast(e); return EnumNamesUnion()[index]; } @@ -117,14 +121,16 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Struct FLATBUFFERS_FINAL_CLASS { double b_; public: - Struct() { - memset(static_cast(this), 0, sizeof(Struct)); + Struct() + : a_(0), + padding0__(0), + b_(0) { + (void)padding0__; } Struct(int32_t _a, double _b) : a_(flatbuffers::EndianScalar(_a)), padding0__(0), b_(flatbuffers::EndianScalar(_b)) { - (void)padding0__; } int32_t a() const { return flatbuffers::EndianScalar(a_); @@ -136,6 +142,7 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Struct FLATBUFFERS_FINAL_CLASS { FLATBUFFERS_STRUCT_END(Struct, 16); struct TableA FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef TableABuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_A = 4, VT_B = 6, @@ -161,6 +168,7 @@ struct TableA FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { }; struct TableABuilder { + typedef TableA Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; void add_a(float a) { @@ -209,6 +217,7 @@ inline flatbuffers::Offset CreateTableADirect( } struct TableB FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef TableBBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_A = 4 }; @@ -223,6 +232,7 @@ struct TableB FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { }; struct TableBBuilder { + typedef TableB Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; void add_a(int32_t a) { @@ -248,6 +258,7 @@ inline flatbuffers::Offset CreateTableB( } struct TableC FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef TableCBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_A = 4, VT_B = 6 @@ -268,6 +279,7 @@ struct TableC FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { }; struct TableCBuilder { + typedef TableC Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; void add_a(double a) { @@ -309,6 +321,7 @@ inline flatbuffers::Offset CreateTableCDirect( } struct Root FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef RootBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_B = 6, VT_C_TYPE = 8, @@ -319,8 +332,8 @@ struct Root FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_G = 18, VT_H = 20, VT_I = 22, - VT_J = 24, - VT_K = 26 + VT_K = 28, + VT_L = 30 }; bool b() const { return GetField(VT_B, 0) != 0; @@ -359,11 +372,11 @@ struct Root FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { uint32_t i() const { return GetField(VT_I, 1234); } - const Evolution::V2::TableC *j() const { - return GetPointer(VT_J); + const Evolution::V2::TableC *k() const { + return GetPointer(VT_K); } - uint8_t k() const { - return GetField(VT_K, 56); + uint8_t l() const { + return GetField(VT_L, 56); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && @@ -381,9 +394,9 @@ struct Root FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { verifier.VerifyVector(h()) && verifier.VerifyVectorOfTables(h()) && VerifyField(verifier, VT_I) && - VerifyOffset(verifier, VT_J) && - verifier.VerifyTable(j()) && - VerifyField(verifier, VT_K) && + VerifyOffset(verifier, VT_K) && + verifier.VerifyTable(k()) && + VerifyField(verifier, VT_L) && verifier.EndTable(); } }; @@ -401,6 +414,7 @@ template<> inline const Evolution::V2::TableC *Root::c_as } struct RootBuilder { + typedef Root Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; void add_b(bool b) { @@ -430,11 +444,11 @@ struct RootBuilder { void add_i(uint32_t i) { fbb_.AddElement(Root::VT_I, i, 1234); } - void add_j(flatbuffers::Offset j) { - fbb_.AddOffset(Root::VT_J, j); + void add_k(flatbuffers::Offset k) { + fbb_.AddOffset(Root::VT_K, k); } - void add_k(uint8_t k) { - fbb_.AddElement(Root::VT_K, k, 56); + void add_l(uint8_t l) { + fbb_.AddElement(Root::VT_L, l, 56); } explicit RootBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { @@ -458,17 +472,17 @@ inline flatbuffers::Offset CreateRoot( flatbuffers::Offset> g = 0, flatbuffers::Offset>> h = 0, uint32_t i = 1234, - flatbuffers::Offset j = 0, - uint8_t k = 56) { + flatbuffers::Offset k = 0, + uint8_t l = 56) { RootBuilder builder_(_fbb); - builder_.add_j(j); + builder_.add_k(k); builder_.add_i(i); builder_.add_h(h); builder_.add_g(g); builder_.add_ff(ff); builder_.add_e(e); builder_.add_c(c); - builder_.add_k(k); + builder_.add_l(l); builder_.add_d(d); builder_.add_c_type(c_type); builder_.add_b(b); @@ -486,8 +500,8 @@ inline flatbuffers::Offset CreateRootDirect( const std::vector *g = nullptr, const std::vector> *h = nullptr, uint32_t i = 1234, - flatbuffers::Offset j = 0, - uint8_t k = 56) { + flatbuffers::Offset k = 0, + uint8_t l = 56) { auto g__ = g ? _fbb.CreateVector(*g) : 0; auto h__ = h ? _fbb.CreateVector>(*h) : 0; return Evolution::V2::CreateRoot( @@ -501,8 +515,8 @@ inline flatbuffers::Offset CreateRootDirect( g__, h__, i, - j, - k); + k, + l); } inline bool VerifyUnion(flatbuffers::Verifier &verifier, const void *obj, Union type) { diff --git a/tests/test.cpp b/tests/test.cpp index 56883cf..cc88be8 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -2490,10 +2490,10 @@ void EvolutionTest() { // Test backwards compatibility by reading old data with an evolved schema. auto root_v1_viewed_from_v2 = Evolution::V2::GetRoot(&binaries[0].front()); - // field 'j' is new in version 2, so it should be null. - TEST_ASSERT(nullptr == root_v1_viewed_from_v2->j()); - // field 'k' is new in version 2 with a default of 56. - TEST_EQ(root_v1_viewed_from_v2->k(), 56); + // field 'k' is new in version 2, so it should be null. + TEST_ASSERT(nullptr == root_v1_viewed_from_v2->k()); + // field 'l' is new in version 2 with a default of 56. + TEST_EQ(root_v1_viewed_from_v2->l(), 56); // field 'c' of 'TableA' is new in version 2, so it should be null. TEST_ASSERT(nullptr == root_v1_viewed_from_v2->e()->c()); // 'TableC' was added to field 'c' union in version 2, so it should be null. @@ -2522,6 +2522,41 @@ void EvolutionTest() { #endif } +void UnionDeprecationTest() { + const int NUM_VERSIONS = 2; + std::string schemas[NUM_VERSIONS]; + std::string jsonfiles[NUM_VERSIONS]; + std::vector binaries[NUM_VERSIONS]; + + flatbuffers::IDLOptions idl_opts; + idl_opts.lang_to_generate |= flatbuffers::IDLOptions::kBinary; + flatbuffers::Parser parser(idl_opts); + + // Load all the schema versions and their associated data. + for (int i = 0; i < NUM_VERSIONS; ++i) { + std::string schema = test_data_path + "evolution_test/evolution_v" + + flatbuffers::NumToString(i + 1) + ".fbs"; + TEST_ASSERT(flatbuffers::LoadFile(schema.c_str(), false, &schemas[i])); + std::string json = test_data_path + "evolution_test/evolution_v" + + flatbuffers::NumToString(i + 1) + ".json"; + TEST_ASSERT(flatbuffers::LoadFile(json.c_str(), false, &jsonfiles[i])); + + TEST_ASSERT(parser.Parse(schemas[i].c_str())); + TEST_ASSERT(parser.Parse(jsonfiles[i].c_str())); + + auto bufLen = parser.builder_.GetSize(); + auto buf = parser.builder_.GetBufferPointer(); + binaries[i].reserve(bufLen); + std::copy(buf, buf + bufLen, std::back_inserter(binaries[i])); + } + + auto v2 = parser.LookupStruct("Evolution.V2.Root"); + TEST_NOTNULL(v2); + auto j_type_field = v2->fields.Lookup("j_type"); + TEST_NOTNULL(j_type_field); + TEST_ASSERT(j_type_field->deprecated); +} + void UnionVectorTest() { // load FlatBuffer fbs schema and json. std::string schemafile, jsonfile; @@ -3420,6 +3455,7 @@ int FlatBufferTests() { ParseProtoTestWithSuffix(); ParseProtoTestWithIncludes(); EvolutionTest(); + UnionDeprecationTest(); UnionVectorTest(); LoadVerifyBinaryTest(); GenerateTableTextTest();