diff options
author | Haibo Huang <hhb@google.com> | 2019-07-10 12:14:05 -0700 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2019-07-10 12:14:05 -0700 |
commit | 47475497d18a84f30fed3535e9804e2ccd403b0b (patch) | |
tree | 75f72f3a91cd3f2d9d4d46ec3ca3d51c044e7bad | |
parent | 830b3208de7a4714a3733dd781a97152ad449e8d (diff) | |
parent | b9c7cbd65c84d1f9bd81b47aa37df697f84a1486 (diff) | |
download | flatbuffers-47475497d18a84f30fed3535e9804e2ccd403b0b.tar.gz |
Upgrade flatbuffer to 'v1.11.0' am: fa7eaaa976 am: 15a5234d98 am: 0328aeeade
am: b9c7cbd65c
Change-Id: Idf577a8c2fde4822607da24398e6eb85e3019f20
52 files changed, 438 insertions, 202 deletions
diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml index 13fc184f..a6e38fde 100644 --- a/.bazelci/presubmit.yml +++ b/.bazelci/presubmit.yml @@ -1,12 +1,12 @@ --- buildifier: latest platforms: - ubuntu1404: + ubuntu1604: build_targets: - "..." test_targets: - "..." - ubuntu1604: + ubuntu1804: build_targets: - "..." test_targets: @@ -26,6 +26,9 @@ **/install_manifest.txt **/CMakeCache.txt **/CMakeTestfile.cmake +**/CPackConfig.cmake +**/CPackSourceConfig.cmake +**/compile_commands.json **/Debug/** **/Release/** **/RelWithDebInfo/** diff --git a/CMakeLists.txt b/CMakeLists.txt index b7acbc7b..119855a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -289,7 +289,7 @@ if(FLATBUFFERS_BUILD_SHAREDLIB) # - minor updated when there are additions in API/ABI # - major (ABI number) updated when there are changes in ABI (or removals) set(FlatBuffers_Library_SONAME_MAJOR "1") - set(FlatBuffers_Library_SONAME_FULL "${FlatBuffers_Library_SONAME_MAJOR}.10.0") + set(FlatBuffers_Library_SONAME_FULL "${FlatBuffers_Library_SONAME_MAJOR}.11.0") set_target_properties(flatbuffers_shared PROPERTIES OUTPUT_NAME flatbuffers SOVERSION "${FlatBuffers_Library_SONAME_MAJOR}" VERSION "${FlatBuffers_Library_SONAME_FULL}") @@ -9,10 +9,10 @@ third_party { type: GIT value: "https://github.com/google/flatbuffers.git" } - version: "b2ce86ef8aef9a9caa8bcc99e54591b92d7b2426" + version: "v1.11.0" last_upgrade_date { year: 2019 - month: 4 - day: 3 + month: 7 + day: 9 } } diff --git a/dart/pubspec.yaml b/dart/pubspec.yaml index 6adf8aab..4761ffc2 100644 --- a/dart/pubspec.yaml +++ b/dart/pubspec.yaml @@ -1,5 +1,5 @@ name: flat_buffers -version: 1.10.0 +version: 1.11.0 description: > FlatBuffers reading and writing library for Dart. Use the flatc compiler to generate Dart classes for a FlatBuffers schema, and this library to assist with diff --git a/docs/source/Schemas.md b/docs/source/Schemas.md index 66c800da..4f7bd728 100644 --- a/docs/source/Schemas.md +++ b/docs/source/Schemas.md @@ -324,8 +324,8 @@ Current understood attributes: Note: currently not guaranteed to have an effect when used with `--object-api`, since that may allocate objects at alignments less than what you specify with `force_align`. -- `bit_flags` (on an enum): the values of this field indicate bits, - meaning that any value N specified in the schema will end up +- `bit_flags` (on an unsigned enum): the values of this field indicate bits, + meaning that any unsigned value N specified in the schema will end up representing 1<<N, or if you don't specify values at all, you'll get the sequence 1, 2, 4, 8, ... - `nested_flatbuffer: "table_name"` (on a field): this indicates that the field diff --git a/docs/source/Tutorial.md b/docs/source/Tutorial.md index 4291c065..e23068b6 100644 --- a/docs/source/Tutorial.md +++ b/docs/source/Tutorial.md @@ -653,14 +653,14 @@ our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`. // Create the first `Weapon` ("Sword"). sample.WeaponStart(builder) - sample.Weapon.AddName(builder, weaponOne) - sample.Weapon.AddDamage(builder, 3) + sample.WeaponAddName(builder, weaponOne) + sample.WeaponAddDamage(builder, 3) sword := sample.WeaponEnd(builder) // Create the second `Weapon` ("Axe"). sample.WeaponStart(builder) - sample.Weapon.AddName(builder, weaponTwo) - sample.Weapon.AddDamage(builder, 5) + sample.WeaponAddName(builder, weaponTwo) + sample.WeaponAddDamage(builder, 5) axe := sample.WeaponEnd(builder) ~~~ </div> @@ -735,10 +735,10 @@ our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`. </div> <div class="language-c"> ~~~{.c} - ns(Weapon_ref_t) weapon_one_name = flatbuffers_string_create_str(B, "Sword"); + flatbuffers_string_ref_t weapon_one_name = flatbuffers_string_create_str(B, "Sword"); uint16_t weapon_one_damage = 3; - ns(Weapon_ref_t) weapon_two_name = flatbuffers_string_create_str(B, "Axe"); + flatbuffers_string_ref_t weapon_two_name = flatbuffers_string_create_str(B, "Axe"); uint16_t weapon_two_damage = 5; ns(Weapon_ref_t) sword = ns(Weapon_create(B, weapon_one_name, weapon_one_damage)); @@ -1922,7 +1922,7 @@ before: <div class="language-cpp"> ~~~{.cpp} - #include "monster_generate.h" // This was generated by `flatc`. + #include "monster_generated.h" // This was generated by `flatc`. using namespace MyGame::Sample; // Specified in the schema. ~~~ diff --git a/docs/source/TypeScriptUsage.md b/docs/source/TypeScriptUsage.md index b773fdfd..832c46ee 100644 --- a/docs/source/TypeScriptUsage.md +++ b/docs/source/TypeScriptUsage.md @@ -17,7 +17,7 @@ documentation to build `flatc` and should be familiar with ## FlatBuffers TypeScript library code location The code for the FlatBuffers TypeScript library can be found at -`flatbuffers/js` with typings available at @types/flatubffers. +`flatbuffers/js` with typings available at `@types/flatbuffers`. ## Testing the FlatBuffers TypeScript library diff --git a/grpc/flatbuffers-java-grpc/pom.xml b/grpc/flatbuffers-java-grpc/pom.xml index 479905b6..40799aea 100644 --- a/grpc/flatbuffers-java-grpc/pom.xml +++ b/grpc/flatbuffers-java-grpc/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>com.google.flatbuffers</groupId> <artifactId>flatbuffers-parent</artifactId> - <version>1.10.0</version> + <version>1.11.0</version> </parent> <artifactId>flatbuffers-java-grpc</artifactId> <name>${project.artifactId}</name> @@ -24,7 +24,7 @@ </developer> </developers> <properties> - <gRPC.version>1.10.0</gRPC.version> + <gRPC.version>1.11.0</gRPC.version> </properties> <dependencies> <dependency> diff --git a/grpc/pom.xml b/grpc/pom.xml index 1f7b2367..c51348d5 100644 --- a/grpc/pom.xml +++ b/grpc/pom.xml @@ -4,7 +4,7 @@ <groupId>com.google.flatbuffers</groupId> <artifactId>flatbuffers-parent</artifactId> <packaging>pom</packaging> - <version>1.10.0</version> + <version>1.11.0</version> <name>flatbuffers-parent</name> <description>parent pom for flatbuffers java artifacts</description> <properties> diff --git a/grpc/tests/pom.xml b/grpc/tests/pom.xml index 53489701..5f8731e5 100644 --- a/grpc/tests/pom.xml +++ b/grpc/tests/pom.xml @@ -4,13 +4,13 @@ <parent> <groupId>com.google.flatbuffers</groupId> <artifactId>flatbuffers-parent</artifactId> - <version>1.10.0</version> + <version>1.11.0</version> </parent> <artifactId>grpc-test</artifactId> <description>Example/Test project demonstrating usage of flatbuffers with GRPC-Java instead of protobufs </description> <properties> - <gRPC.version>1.10.0</gRPC.version> + <gRPC.version>1.11.0</gRPC.version> </properties> <dependencies> <dependency> diff --git a/include/flatbuffers/base.h b/include/flatbuffers/base.h index a64a587f..ee8021fd 100644 --- a/include/flatbuffers/base.h +++ b/include/flatbuffers/base.h @@ -136,7 +136,7 @@ #endif // !defined(FLATBUFFERS_LITTLEENDIAN) #define FLATBUFFERS_VERSION_MAJOR 1 -#define FLATBUFFERS_VERSION_MINOR 10 +#define FLATBUFFERS_VERSION_MINOR 11 #define FLATBUFFERS_VERSION_REVISION 0 #define FLATBUFFERS_STRING_EXPAND(X) #X #define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X) diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 05d666cb..8299fe0c 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -334,6 +334,8 @@ struct EnumVal { Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder, const Parser &parser) const; bool Deserialize(const Parser &parser, const reflection::EnumVal *val); + bool IsZero() const { return 0 == value; } + bool IsNonZero() const { return !IsZero(); } std::string name; std::vector<std::string> doc_comment; @@ -345,9 +347,9 @@ struct EnumDef : public Definition { EnumDef() : is_union(false), uses_multiple_type_instances(false) {} EnumVal *ReverseLookup(int64_t enum_idx, bool skip_union_default = true) { - for (auto it = vals.vec.begin() + + for (auto it = Vals().begin() + static_cast<int>(is_union && skip_union_default); - it != vals.vec.end(); ++it) { + it != Vals().end(); ++it) { if ((*it)->value == enum_idx) { return *it; } } return nullptr; @@ -357,6 +359,12 @@ struct EnumDef : public Definition { bool Deserialize(Parser &parser, const reflection::Enum *values); + size_t size() const { return vals.vec.size(); } + + const std::vector<EnumVal *> &Vals() const { + return vals.vec; + } + SymbolTable<EnumVal> vals; bool is_union; // Type is a union which uses type aliases where at least one type is @@ -691,17 +699,15 @@ class Parser : public ParserState { bool ParseFlexBuffer(const char *source, const char *source_filename, flexbuffers::Builder *builder); - FLATBUFFERS_CHECKED_ERROR InvalidNumber(const char *number, - const std::string &msg); - StructDef *LookupStruct(const std::string &id) const; std::string UnqualifiedName(std::string fullQualifiedName); + FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg); + private: void Message(const std::string &msg); void Warning(const std::string &msg); - FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg); FLATBUFFERS_CHECKED_ERROR ParseHexNum(int nibbles, uint64_t *val); FLATBUFFERS_CHECKED_ERROR Next(); FLATBUFFERS_CHECKED_ERROR SkipByteOrderMark(); @@ -745,7 +751,7 @@ class Parser : public ParserState { FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef* field); FLATBUFFERS_CHECKED_ERROR TokenError(); FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e, bool check_now); - FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(Type &type, int64_t *result); + FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type &type, std::string *result); StructDef *LookupCreateStruct(const std::string &name, bool create_if_new = true, bool definition = false); @@ -834,6 +840,10 @@ extern std::string MakeCamel(const std::string &in, bool first = true); // strict_json adds "quotes" around field names if true. // If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8 // byte arrays in String values), returns false. +extern bool GenerateTextFromTable(const Parser &parser, + const void *table, + const std::string &tablename, + std::string *text); extern bool GenerateText(const Parser &parser, const void *flatbuffer, std::string *text); diff --git a/js/flatbuffers.js b/js/flatbuffers.js index 0c970bd8..41608520 100644 --- a/js/flatbuffers.js +++ b/js/flatbuffers.js @@ -829,7 +829,6 @@ flatbuffers.ByteBuffer = function(bytes) { * @private */ this.position_ = 0; - }; /** @@ -842,7 +841,7 @@ flatbuffers.ByteBuffer.allocate = function(byte_size) { return new flatbuffers.ByteBuffer(new Uint8Array(byte_size)); }; -flatbuffers.ByteBuffer.prototype.clear = function() { +flatbuffers.ByteBuffer.prototype.clear = function() { this.position_ = 0; }; diff --git a/package.json b/package.json index daf76b07..f95e7540 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "flatbuffers", - "version": "1.10.2", + "version": "1.11.0", "description": "Memory Efficient Serialization Library", "files": [ "js/flatbuffers.js", @@ -5,7 +5,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>com.google.flatbuffers</groupId> <artifactId>flatbuffers-java</artifactId> - <version>1.10.1-SNAPSHOT</version> + <version>1.11.0-SNAPSHOT</version> <packaging>bundle</packaging> <name>FlatBuffers Java API</name> <description> diff --git a/rust/flatbuffers/Cargo.toml b/rust/flatbuffers/Cargo.toml index 67bbd8d0..32d9b1b8 100644 --- a/rust/flatbuffers/Cargo.toml +++ b/rust/flatbuffers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "flatbuffers" -version = "0.5.0" +version = "0.6.0" authors = ["Robert Winslow <hello@rwinslow.com>", "FlatBuffers Maintainers"] license = "Apache-2.0" description = "Official FlatBuffers Rust runtime library." diff --git a/samples/monster.bfbs b/samples/monster.bfbs Binary files differindex 95a977a3..061a17b6 100644 --- a/samples/monster.bfbs +++ b/samples/monster.bfbs diff --git a/samples/monster.fbs b/samples/monster.fbs index 247b8177..af224512 100644 --- a/samples/monster.fbs +++ b/samples/monster.fbs @@ -22,6 +22,7 @@ table Monster { color:Color = Blue; weapons:[Weapon]; equipped:Equipment; + path:[Vec3]; } table Weapon { diff --git a/samples/monster_generated.h b/samples/monster_generated.h index 84e81602..7026116d 100644 --- a/samples/monster_generated.h +++ b/samples/monster_generated.h @@ -121,10 +121,11 @@ struct EquipmentUnion { #ifndef FLATBUFFERS_CPP98_STL template <typename T> void Set(T&& val) { + using RT = typename std::remove_reference<T>::type; Reset(); - type = EquipmentTraits<typename T::TableType>::enum_value; + type = EquipmentTraits<typename RT::TableType>::enum_value; if (type != Equipment_NONE) { - value = new T(std::forward<T>(val)); + value = new RT(std::forward<T>(val)); } } #endif // FLATBUFFERS_CPP98_STL @@ -173,6 +174,9 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vec3 FLATBUFFERS_FINAL_CLASS { float z_; public: + static const flatbuffers::TypeTable *MiniReflectTypeTable() { + return Vec3TypeTable(); + } Vec3() { memset(static_cast<void *>(this), 0, sizeof(Vec3)); } @@ -224,6 +228,7 @@ struct MonsterT : public flatbuffers::NativeTable { Color color; std::vector<flatbuffers::unique_ptr<WeaponT>> weapons; EquipmentUnion equipped; + std::vector<Vec3> path; MonsterT() : mana(150), hp(100), @@ -240,7 +245,8 @@ inline bool operator==(const MonsterT &lhs, const MonsterT &rhs) { (lhs.inventory == rhs.inventory) && (lhs.color == rhs.color) && (lhs.weapons == rhs.weapons) && - (lhs.equipped == rhs.equipped); + (lhs.equipped == rhs.equipped) && + (lhs.path == rhs.path); } inline bool operator!=(const MonsterT &lhs, const MonsterT &rhs) { @@ -262,7 +268,8 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_COLOR = 16, VT_WEAPONS = 18, VT_EQUIPPED_TYPE = 20, - VT_EQUIPPED = 22 + VT_EQUIPPED = 22, + VT_PATH = 24 }; const Vec3 *pos() const { return GetStruct<const Vec3 *>(VT_POS); @@ -322,6 +329,12 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { void *mutable_equipped() { return GetPointer<void *>(VT_EQUIPPED); } + const flatbuffers::Vector<const Vec3 *> *path() const { + return GetPointer<const flatbuffers::Vector<const Vec3 *> *>(VT_PATH); + } + flatbuffers::Vector<const Vec3 *> *mutable_path() { + return GetPointer<flatbuffers::Vector<const Vec3 *> *>(VT_PATH); + } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyField<Vec3>(verifier, VT_POS) && @@ -338,6 +351,8 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyField<uint8_t>(verifier, VT_EQUIPPED_TYPE) && VerifyOffset(verifier, VT_EQUIPPED) && VerifyEquipment(verifier, equipped(), equipped_type()) && + VerifyOffset(verifier, VT_PATH) && + verifier.VerifyVector(path()) && verifier.EndTable(); } MonsterT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; @@ -379,6 +394,9 @@ struct MonsterBuilder { void add_equipped(flatbuffers::Offset<void> equipped) { fbb_.AddOffset(Monster::VT_EQUIPPED, equipped); } + void add_path(flatbuffers::Offset<flatbuffers::Vector<const Vec3 *>> path) { + fbb_.AddOffset(Monster::VT_PATH, path); + } explicit MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); @@ -401,8 +419,10 @@ inline flatbuffers::Offset<Monster> CreateMonster( Color color = Color_Blue, flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Weapon>>> weapons = 0, Equipment equipped_type = Equipment_NONE, - flatbuffers::Offset<void> equipped = 0) { + flatbuffers::Offset<void> equipped = 0, + flatbuffers::Offset<flatbuffers::Vector<const Vec3 *>> path = 0) { MonsterBuilder builder_(_fbb); + builder_.add_path(path); builder_.add_equipped(equipped); builder_.add_weapons(weapons); builder_.add_inventory(inventory); @@ -425,10 +445,12 @@ inline flatbuffers::Offset<Monster> CreateMonsterDirect( Color color = Color_Blue, const std::vector<flatbuffers::Offset<Weapon>> *weapons = nullptr, Equipment equipped_type = Equipment_NONE, - flatbuffers::Offset<void> equipped = 0) { + flatbuffers::Offset<void> equipped = 0, + const std::vector<Vec3> *path = nullptr) { auto name__ = name ? _fbb.CreateString(name) : 0; auto inventory__ = inventory ? _fbb.CreateVector<uint8_t>(*inventory) : 0; auto weapons__ = weapons ? _fbb.CreateVector<flatbuffers::Offset<Weapon>>(*weapons) : 0; + auto path__ = path ? _fbb.CreateVectorOfStructs<Vec3>(*path) : 0; return MyGame::Sample::CreateMonster( _fbb, pos, @@ -439,7 +461,8 @@ inline flatbuffers::Offset<Monster> CreateMonsterDirect( color, weapons__, equipped_type, - equipped); + equipped, + path__); } flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); @@ -559,6 +582,7 @@ inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function { auto _e = weapons(); if (_e) { _o->weapons.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->weapons[_i] = flatbuffers::unique_ptr<WeaponT>(_e->Get(_i)->UnPack(_resolver)); } } }; { auto _e = equipped_type(); _o->equipped.type = _e; }; { auto _e = equipped(); if (_e) _o->equipped.value = EquipmentUnion::UnPack(_e, equipped_type(), _resolver); }; + { auto _e = path(); if (_e) { _o->path.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->path[_i] = *_e->Get(_i); } } }; } inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) { @@ -578,6 +602,7 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder auto _weapons = _o->weapons.size() ? _fbb.CreateVector<flatbuffers::Offset<Weapon>> (_o->weapons.size(), [](size_t i, _VectorArgs *__va) { return CreateWeapon(*__va->__fbb, __va->__o->weapons[i].get(), __va->__rehasher); }, &_va ) : 0; auto _equipped_type = _o->equipped.type; auto _equipped = _o->equipped.Pack(_fbb); + auto _path = _o->path.size() ? _fbb.CreateVectorOfStructs(_o->path) : 0; return MyGame::Sample::CreateMonster( _fbb, _pos, @@ -588,7 +613,8 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder _color, _weapons, _equipped_type, - _equipped); + _equipped, + _path); } inline WeaponT *Weapon::UnPack(const flatbuffers::resolver_function_t *_resolver) const { @@ -756,7 +782,8 @@ inline const flatbuffers::TypeTable *MonsterTypeTable() { { flatbuffers::ET_CHAR, 0, 1 }, { flatbuffers::ET_SEQUENCE, 1, 2 }, { flatbuffers::ET_UTYPE, 0, 3 }, - { flatbuffers::ET_SEQUENCE, 0, 3 } + { flatbuffers::ET_SEQUENCE, 0, 3 }, + { flatbuffers::ET_SEQUENCE, 1, 0 } }; static const flatbuffers::TypeFunction type_refs[] = { Vec3TypeTable, @@ -774,10 +801,11 @@ inline const flatbuffers::TypeTable *MonsterTypeTable() { "color", "weapons", "equipped_type", - "equipped" + "equipped", + "path" }; static const flatbuffers::TypeTable tt = { - flatbuffers::ST_TABLE, 10, type_codes, type_refs, nullptr, names + flatbuffers::ST_TABLE, 11, type_codes, type_refs, nullptr, names }; return &tt; } diff --git a/samples/monster_generated.lobster b/samples/monster_generated.lobster index c1a31996..409e77d7 100644 --- a/samples/monster_generated.lobster +++ b/samples/monster_generated.lobster @@ -58,11 +58,15 @@ struct Monster : flatbuffers_handle buf_.flatbuffers_field_int8(pos_, 20, 0) def equipped_as_Weapon(): MyGame_Sample_Weapon { buf_, buf_.flatbuffers_field_table(pos_, 22) } + def path(i:int): + MyGame_Sample_Vec3 { buf_, buf_.flatbuffers_field_vector(pos_, 24) + i * 12 } + def path_length(): + buf_.flatbuffers_field_vector_len(pos_, 24) def GetRootAsMonster(buf:string): Monster { buf, buf.flatbuffers_indirect(0) } def MonsterStart(b_:flatbuffers_builder): - b_.StartObject(10) + b_.StartObject(11) def MonsterAddPos(b_:flatbuffers_builder, pos:int): b_.PrependStructSlot(0, pos, 0) def MonsterAddMana(b_:flatbuffers_builder, mana:int): @@ -93,6 +97,10 @@ def MonsterAddEquippedType(b_:flatbuffers_builder, equipped_type:int): b_.PrependUint8Slot(8, equipped_type, 0) def MonsterAddEquipped(b_:flatbuffers_builder, equipped:int): b_.PrependUOffsetTRelativeSlot(9, equipped, 0) +def MonsterAddPath(b_:flatbuffers_builder, path:int): + b_.PrependUOffsetTRelativeSlot(10, path, 0) +def MonsterStartPathVector(b_:flatbuffers_builder, n_:int): + b_.StartVector(12, n_, 4) def MonsterEnd(b_:flatbuffers_builder): b_.EndObject() diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml new file mode 100644 index 00000000..17138961 --- /dev/null +++ b/snap/snapcraft.yaml @@ -0,0 +1,37 @@ +name: flatbuffers +base: core18 +version: latest +version-script: git describe --always | sed -e 's/-/+git/;y/-/./' | tail -c +2 +summary: FlatBuffers compiler +description: | + FlatBuffers compiler + + NOTE: This snap also ships the necessary header files required to compile + projects using flatbuffers, however, for the compilation to work, you have + to manually add the following path in your project's configuration: + + /snap/flatbuffers/current/include + + If you need to use flatbuffers headers from a location other than the above + path, it is recommended to not use this snap as that could cause a mismatch. + +grade: stable +confinement: strict + +parts: + flatc: + plugin: cmake + source: . + configflags: + - -GUnix Makefiles + - -DCMAKE_BUILD_TYPE=Release + build-packages: + - g++ + # used to set version number + - git + +apps: + flatc: + command: flatc + plugs: + - home diff --git a/src/flatc.cpp b/src/flatc.cpp index 3833f3de..78e4c5bf 100644 --- a/src/flatc.cpp +++ b/src/flatc.cpp @@ -18,7 +18,7 @@ #include <list> -#define FLATC_VERSION "1.10.0" +#define FLATC_VERSION "1.11.0" namespace flatbuffers { @@ -30,8 +30,10 @@ void FlatCompiler::ParseFile( include_directories.push_back(local_include_directory.c_str()); include_directories.push_back(nullptr); if (!parser.Parse(contents.c_str(), &include_directories[0], - filename.c_str())) + filename.c_str())) { Error(parser.error_, false, false); + } + if (!parser.error_.empty()) { Warn(parser.error_, false); } include_directories.pop_back(); include_directories.pop_back(); } diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index 50cb82fa..268c436e 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -785,7 +785,7 @@ class CppGenerator : public BaseGenerator { struct_def ? (struct_def->fixed ? "ST_STRUCT" : "ST_TABLE") : (enum_def->is_union ? "ST_UNION" : "ST_ENUM")); auto num_fields = - struct_def ? struct_def->fields.vec.size() : enum_def->vals.vec.size(); + struct_def ? struct_def->fields.vec.size() : enum_def->size(); code_.SetValue("NUM_FIELDS", NumToString(num_fields)); std::vector<std::string> names; std::vector<Type> types; @@ -798,13 +798,13 @@ class CppGenerator : public BaseGenerator { types.push_back(field.value.type); } } else { - for (auto it = enum_def->vals.vec.begin(); it != enum_def->vals.vec.end(); + for (auto it = enum_def->Vals().begin(); it != enum_def->Vals().end(); ++it) { const auto &ev = **it; names.push_back(Name(ev)); types.push_back(enum_def->is_union ? ev.union_type : Type(enum_def->underlying_type)); - if (static_cast<int64_t>(it - enum_def->vals.vec.begin()) != ev.value) { + if (static_cast<int64_t>(it - enum_def->Vals().begin()) != ev.value) { consecutive_enum_from_zero = false; } } @@ -852,7 +852,7 @@ class CppGenerator : public BaseGenerator { } std::string vs; if (enum_def && !consecutive_enum_from_zero) { - for (auto it = enum_def->vals.vec.begin(); it != enum_def->vals.vec.end(); + for (auto it = enum_def->Vals().begin(); it != enum_def->Vals().end(); ++it) { const auto &ev = **it; if (!vs.empty()) vs += ", "; @@ -919,8 +919,7 @@ class CppGenerator : public BaseGenerator { int64_t anyv = 0; const EnumVal *minv = nullptr, *maxv = nullptr; - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); - ++it) { + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { const auto &ev = **it; GenComment(ev.doc_comment, " "); @@ -966,15 +965,14 @@ class CppGenerator : public BaseGenerator { code_ += ""; // Generate an array of all enumeration values - auto num_fields = NumToString(enum_def.vals.vec.size()); + auto num_fields = NumToString(enum_def.size()); code_ += "inline const {{ENUM_NAME}} (&EnumValues{{ENUM_NAME}}())[" + num_fields + "] {"; code_ += " static const {{ENUM_NAME}} values[] = {"; - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); - ++it) { + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { const auto &ev = **it; auto value = GetEnumValUse(enum_def, ev); - auto suffix = *it != enum_def.vals.vec.back() ? "," : ""; + auto suffix = *it != enum_def.Vals().back() ? "," : ""; code_ += " " + value + suffix; } code_ += " };"; @@ -996,8 +994,8 @@ class CppGenerator : public BaseGenerator { code_ += "inline const char * const *EnumNames{{ENUM_NAME}}() {"; code_ += " static const char * const names[] = {"; - auto val = enum_def.vals.vec.front()->value; - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); + auto val = enum_def.Vals().front()->value; + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { const auto &ev = **it; while (val++ != ev.value) { code_ += " \"\","; } @@ -1032,7 +1030,7 @@ class CppGenerator : public BaseGenerator { code_ += " switch (e) {"; - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { const auto &ev = **it; code_ += " case " + GetEnumValUse(enum_def, ev) + ": return \"" + @@ -1048,11 +1046,11 @@ class CppGenerator : public BaseGenerator { // Generate type traits for unions to map from a type to union enum value. if (enum_def.is_union && !enum_def.uses_multiple_type_instances) { - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { const auto &ev = **it; - if (it == enum_def.vals.vec.begin()) { + if (it == enum_def.Vals().begin()) { code_ += "template<typename T> struct {{ENUM_NAME}}Traits {"; } else { auto name = GetUnionElement(ev, true, true); @@ -1100,11 +1098,11 @@ class CppGenerator : public BaseGenerator { code_ += "#ifndef FLATBUFFERS_CPP98_STL"; code_ += " template <typename T>"; code_ += " void Set(T&& val) {"; + code_ += " using RT = typename std::remove_reference<T>::type;"; code_ += " Reset();"; - code_ += - " type = {{NAME}}Traits<typename T::TableType>::enum_value;"; + code_ += " type = {{NAME}}Traits<typename RT::TableType>::enum_value;"; code_ += " if (type != {{NONE}}) {"; - code_ += " value = new T(std::forward<T>(val));"; + code_ += " value = new RT(std::forward<T>(val));"; code_ += " }"; code_ += " }"; code_ += "#endif // FLATBUFFERS_CPP98_STL"; @@ -1114,10 +1112,10 @@ class CppGenerator : public BaseGenerator { code_ += " " + UnionPackSignature(enum_def, true) + ";"; code_ += ""; - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { const auto &ev = **it; - if (!ev.value) { continue; } + if (ev.IsZero()) { continue; } const auto native_type = NativeName(GetUnionElement(ev, true, true, true), @@ -1148,11 +1146,11 @@ class CppGenerator : public BaseGenerator { code_ += " if (lhs.type != rhs.type) return false;"; code_ += " switch (lhs.type) {"; - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { const auto &ev = **it; code_.SetValue("NATIVE_ID", GetEnumValUse(enum_def, ev)); - if (ev.value) { + if (ev.IsNonZero()) { const auto native_type = NativeName(GetUnionElement(ev, true, true, true), ev.union_type.struct_def, parser_.opts); @@ -1204,19 +1202,19 @@ class CppGenerator : public BaseGenerator { code_ += "inline " + UnionVerifySignature(enum_def) + " {"; code_ += " switch (type) {"; - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); - ++it) { + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { const auto &ev = **it; code_.SetValue("LABEL", GetEnumValUse(enum_def, ev)); - if (ev.value) { + if (ev.IsNonZero()) { code_.SetValue("TYPE", GetUnionElement(ev, true, true)); code_ += " case {{LABEL}}: {"; auto getptr = " auto ptr = reinterpret_cast<const {{TYPE}} *>(obj);"; if (ev.union_type.base_type == BASE_TYPE_STRUCT) { if (ev.union_type.struct_def->fixed) { - code_ += " return true;"; + code_ += " return verifier.Verify<{{TYPE}}>(static_cast<const " + "uint8_t *>(obj), 0);"; } else { code_ += getptr; code_ += " return verifier.VerifyTable(ptr);"; @@ -1257,10 +1255,10 @@ class CppGenerator : public BaseGenerator { // Generate union Unpack() and Pack() functions. code_ += "inline " + UnionUnPackSignature(enum_def, false) + " {"; code_ += " switch (type) {"; - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { const auto &ev = **it; - if (!ev.value) { continue; } + if (ev.IsZero()) { continue; } code_.SetValue("LABEL", GetEnumValUse(enum_def, ev)); code_.SetValue("TYPE", GetUnionElement(ev, true, true)); @@ -1287,10 +1285,10 @@ class CppGenerator : public BaseGenerator { code_ += "inline " + UnionPackSignature(enum_def, false) + " {"; code_ += " switch (type) {"; - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { auto &ev = **it; - if (!ev.value) { continue; } + if (ev.IsZero()) { continue; } code_.SetValue("LABEL", GetEnumValUse(enum_def, ev)); code_.SetValue("TYPE", @@ -1324,10 +1322,10 @@ class CppGenerator : public BaseGenerator { "{{ENUM_NAME}}Union &u) FLATBUFFERS_NOEXCEPT : type(u.type), " "value(nullptr) {"; code_ += " switch (type) {"; - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { const auto &ev = **it; - if (!ev.value) { continue; } + if (ev.IsZero()) { continue; } code_.SetValue("LABEL", GetEnumValUse(enum_def, ev)); code_.SetValue("TYPE", NativeName(GetUnionElement(ev, true, true, true), @@ -1370,10 +1368,10 @@ class CppGenerator : public BaseGenerator { code_ += "inline void {{ENUM_NAME}}Union::Reset() {"; code_ += " switch (type) {"; - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { const auto &ev = **it; - if (!ev.value) { continue; } + if (ev.IsZero()) { continue; } code_.SetValue("LABEL", GetEnumValUse(enum_def, ev)); code_.SetValue("TYPE", NativeName(GetUnionElement(ev, true, true, true), @@ -1834,8 +1832,7 @@ class CppGenerator : public BaseGenerator { " template<typename T> " "const T *{{NULLABLE_EXT}}{{FIELD_NAME}}_as() const;"; - for (auto u_it = u->vals.vec.begin(); u_it != u->vals.vec.end(); - ++u_it) { + for (auto u_it = u->Vals().begin(); u_it != u->Vals().end(); ++u_it) { auto &ev = **u_it; if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; } auto full_struct_name = GetUnionElement(ev, true, true); @@ -1967,7 +1964,7 @@ class CppGenerator : public BaseGenerator { code_.SetValue("FIELD_NAME", Name(field)); - for (auto u_it = u->vals.vec.begin(); u_it != u->vals.vec.end(); ++u_it) { + for (auto u_it = u->Vals().begin(); u_it != u->Vals().end(); ++u_it) { auto &ev = **u_it; if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; } @@ -2688,6 +2685,15 @@ class CppGenerator : public BaseGenerator { // Generate GetFullyQualifiedName code_ += ""; code_ += " public:"; + + // Make TypeTable accessible via the generated struct. + if (parser_.opts.mini_reflect != IDLOptions::kNone) { + code_ += + " static const flatbuffers::TypeTable *MiniReflectTypeTable() {"; + code_ += " return {{STRUCT_NAME}}TypeTable();"; + code_ += " }"; + } + GenFullyQualifiedNameGetter(struct_def, Name(struct_def)); // Generate a default constructor. diff --git a/src/idl_gen_dart.cpp b/src/idl_gen_dart.cpp index fb7e0bdf..2141eb38 100644 --- a/src/idl_gen_dart.cpp +++ b/src/idl_gen_dart.cpp @@ -251,12 +251,11 @@ class DartGenerator : public BaseGenerator { " static bool containsValue(int value) =>" " values.containsKey(value);\n\n"; - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); - ++it) { + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { auto &ev = **it; if (!ev.doc_comment.empty()) { - if (it != enum_def.vals.vec.begin()) { code += '\n'; } + if (it != enum_def.Vals().begin()) { code += '\n'; } GenDocComment(ev.doc_comment, &code, "", " "); } code += " static const " + name + " " + ev.name + " = "; @@ -264,8 +263,7 @@ class DartGenerator : public BaseGenerator { } code += " static get values => {"; - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); - ++it) { + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { auto &ev = **it; code += NumToString(ev.value) + ": " + ev.name + ","; } @@ -503,8 +501,9 @@ class DartGenerator : public BaseGenerator { if (field.value.type.base_type == BASE_TYPE_UNION) { code += " {\n"; code += " switch (" + field_name + "Type?.value) {\n"; - for (auto en_it = field.value.type.enum_def->vals.vec.begin() + 1; - en_it != field.value.type.enum_def->vals.vec.end(); ++en_it) { + auto &enum_def = *field.value.type.enum_def; + for (auto en_it = enum_def.Vals().begin() + 1; + en_it != enum_def.Vals().end(); ++en_it) { auto &ev = **en_it; auto enum_name = NamespaceAliasFromUnionType(ev.name); diff --git a/src/idl_gen_fbs.cpp b/src/idl_gen_fbs.cpp index 37c60267..5a85a955 100644 --- a/src/idl_gen_fbs.cpp +++ b/src/idl_gen_fbs.cpp @@ -96,8 +96,7 @@ std::string GenerateFBS(const Parser &parser, const std::string &file_name) { else schema += "enum " + enum_def.name + " : "; schema += GenType(enum_def.underlying_type, true) + " {\n"; - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); - ++it) { + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { auto &ev = **it; GenComment(ev.doc_comment, &schema, nullptr, " "); if (enum_def.is_union) diff --git a/src/idl_gen_general.cpp b/src/idl_gen_general.cpp index 5fa9b184..fe793bf3 100644 --- a/src/idl_gen_general.cpp +++ b/src/idl_gen_general.cpp @@ -543,8 +543,7 @@ class GeneralGenerator : public BaseGenerator { if (lang_.language == IDLOptions::kJava) { code += " private " + enum_def.name + "() { }\n"; } - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); - ++it) { + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { auto &ev = **it; GenComment(ev.doc_comment, code_ptr, &lang_.comment_config, " "); if (lang_.language != IDLOptions::kCSharp) { @@ -574,8 +573,8 @@ class GeneralGenerator : public BaseGenerator { code += lang_.const_decl; code += lang_.string_type; code += "[] names = { "; - auto val = enum_def.vals.vec.front()->value; - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); + auto val = enum_def.Vals().front()->value; + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { while (val++ != (*it)->value) code += "\"\", "; code += "\"" + (*it)->name + "\", "; @@ -1044,7 +1043,7 @@ class GeneralGenerator : public BaseGenerator { : lang_.accessor_prefix + "__indirect(" + index + ")"; code += ", " + lang_.accessor_prefix + "bb"; } else if (vectortype.base_type == BASE_TYPE_UNION) { - code += index + " - bb_pos"; + code += index + " - " + lang_.accessor_prefix + "bb_pos"; } else { code += index; } diff --git a/src/idl_gen_go.cpp b/src/idl_gen_go.cpp index 7a68e8aa..412d1e82 100644 --- a/src/idl_gen_go.cpp +++ b/src/idl_gen_go.cpp @@ -153,7 +153,7 @@ class GoGenerator : public BaseGenerator { } // A single enum member. - void EnumMember(const EnumDef &enum_def, const EnumVal ev, + void EnumMember(const EnumDef &enum_def, const EnumVal &ev, std::string *code_ptr) { std::string &code = *code_ptr; code += "\t"; @@ -725,8 +725,7 @@ class GoGenerator : public BaseGenerator { GenComment(enum_def.doc_comment, code_ptr, nullptr); GenEnumType(enum_def, code_ptr); BeginEnum(code_ptr); - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); - ++it) { + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { auto &ev = **it; GenComment(ev.doc_comment, code_ptr, nullptr, "\t"); EnumMember(enum_def, ev, code_ptr); @@ -734,8 +733,7 @@ class GoGenerator : public BaseGenerator { EndEnum(code_ptr); BeginEnumNames(enum_def, code_ptr); - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); - ++it) { + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { auto &ev = **it; EnumNameMember(enum_def, ev, code_ptr); } diff --git a/src/idl_gen_js_ts.cpp b/src/idl_gen_js_ts.cpp index 9b7942b0..fea46208 100644 --- a/src/idl_gen_js_ts.cpp +++ b/src/idl_gen_js_ts.cpp @@ -350,11 +350,10 @@ class JsTsGenerator : public BaseGenerator { } code += WrapInNameSpace(enum_def) + (reverse ? "Name" : "") + " = {\n"; } - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); - ++it) { + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { auto &ev = **it; if (!ev.doc_comment.empty()) { - if (it != enum_def.vals.vec.begin()) { code += '\n'; } + if (it != enum_def.Vals().begin()) { code += '\n'; } GenDocComment(ev.doc_comment, code_ptr, "", " "); } @@ -369,7 +368,7 @@ class JsTsGenerator : public BaseGenerator { code += NumToString(ev.value); } - code += (it + 1) != enum_def.vals.vec.end() ? ",\n" : "\n"; + code += (it + 1) != enum_def.Vals().end() ? ",\n" : "\n"; if (ev.union_type.struct_def) { ReexportDescription desc = { ev.name, diff --git a/src/idl_gen_json_schema.cpp b/src/idl_gen_json_schema.cpp index 18835801..a0f193b5 100644 --- a/src/idl_gen_json_schema.cpp +++ b/src/idl_gen_json_schema.cpp @@ -86,7 +86,7 @@ std::string GenType(const Type &type) { } case BASE_TYPE_UNION: { std::string union_type_string("\"anyOf\": ["); - const auto &union_types = type.enum_def->vals.vec; + const auto &union_types = type.enum_def->Vals(); for (auto ut = union_types.cbegin(); ut < union_types.cend(); ++ut) { auto &union_type = *ut; if (union_type->union_type.base_type == BASE_TYPE_NONE) { continue; } @@ -94,7 +94,7 @@ std::string GenType(const Type &type) { union_type_string.append( "{ " + GenTypeRef(union_type->union_type.struct_def) + " }"); } - if (union_type != *type.enum_def->vals.vec.rbegin()) { + if (union_type != *type.enum_def->Vals().rbegin()) { union_type_string.append(","); } } @@ -128,10 +128,10 @@ class JsonSchemaGenerator : public BaseGenerator { code_ += " \"" + GenFullName(*e) + "\" : {"; code_ += " " + GenType("string") + ","; std::string enumdef(" \"enum\": ["); - for (auto enum_value = (*e)->vals.vec.begin(); - enum_value != (*e)->vals.vec.end(); ++enum_value) { + for (auto enum_value = (*e)->Vals().begin(); + enum_value != (*e)->Vals().end(); ++enum_value) { enumdef.append("\"" + (*enum_value)->name + "\""); - if (*enum_value != (*e)->vals.vec.back()) { enumdef.append(", "); } + if (*enum_value != (*e)->Vals().back()) { enumdef.append(", "); } } enumdef.append("]"); code_ += enumdef; diff --git a/src/idl_gen_lobster.cpp b/src/idl_gen_lobster.cpp index 5f199e3a..fe23d970 100644 --- a/src/idl_gen_lobster.cpp +++ b/src/idl_gen_lobster.cpp @@ -149,10 +149,10 @@ class LobsterGenerator : public BaseGenerator { break; } case BASE_TYPE_UNION: { - for (auto it = field.value.type.enum_def->vals.vec.begin(); - it != field.value.type.enum_def->vals.vec.end(); ++it) { + for (auto it = field.value.type.enum_def->Vals().begin(); + it != field.value.type.enum_def->Vals().end(); ++it) { auto &ev = **it; - if (ev.value) { + if (ev.IsNonZero()) { code += def + "_as_" + ev.name + "():\n " + NamespacedName(*ev.union_type.struct_def) + " { buf_, buf_.flatbuffers_field_table(pos_, " + offsets + @@ -259,13 +259,12 @@ class LobsterGenerator : public BaseGenerator { CheckNameSpace(enum_def, &code); GenComment(enum_def.doc_comment, code_ptr, nullptr, ""); code += "enum + \n"; - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); - ++it) { + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { auto &ev = **it; GenComment(ev.doc_comment, code_ptr, nullptr, " "); code += " " + enum_def.name + "_" + NormalizedName(ev) + " = " + NumToString(ev.value); - if (it + 1 != enum_def.vals.vec.end()) code += ","; + if (it + 1 != enum_def.Vals().end()) code += ","; code += "\n"; } code += "\n"; diff --git a/src/idl_gen_lua.cpp b/src/idl_gen_lua.cpp index e8ae3280..b26f9070 100644 --- a/src/idl_gen_lua.cpp +++ b/src/idl_gen_lua.cpp @@ -109,9 +109,10 @@ namespace lua { } // A single enum member. - void EnumMember(const EnumVal ev, std::string *code_ptr) { + void EnumMember(const EnumDef &enum_def, const EnumVal &ev, std::string *code_ptr) { std::string &code = *code_ptr; code += std::string(Indent) + NormalizedName(ev) + " = " + NumToString(ev.value) + ",\n"; + (void)enum_def; } // End enum code. @@ -336,7 +337,7 @@ namespace lua { } code += EndFunc; } - + // Begin the creator function signature. void BeginBuilderArgs(const StructDef &struct_def, std::string *code_ptr) { @@ -497,7 +498,7 @@ namespace lua { GetMemberOfVectorOfStruct(struct_def, field, code_ptr); } else { - GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr); + GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr); } break; } @@ -572,11 +573,11 @@ namespace lua { GenComment(enum_def.doc_comment, code_ptr, nullptr, Comment); BeginEnum(NormalizedName(enum_def), code_ptr); - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); - ++it) { + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); + ++it) { auto &ev = **it; GenComment(ev.doc_comment, code_ptr, nullptr, Comment); - EnumMember(ev, code_ptr); + EnumMember(enum_def, ev, code_ptr); } EndEnum(code_ptr); } diff --git a/src/idl_gen_php.cpp b/src/idl_gen_php.cpp index 3c6747e3..a4b9a469 100644 --- a/src/idl_gen_php.cpp +++ b/src/idl_gen_php.cpp @@ -119,12 +119,14 @@ class PhpGenerator : public BaseGenerator { } // A single enum member. - static void EnumMember(const EnumVal ev, std::string *code_ptr) { + static void EnumMember(const EnumDef &enum_def, const EnumVal &ev, + std::string *code_ptr) { std::string &code = *code_ptr; code += Indent + "const "; code += ev.name; code += " = "; code += NumToString(ev.value) + ";\n"; + (void)enum_def; } // End enum code. @@ -815,18 +817,16 @@ class PhpGenerator : public BaseGenerator { GenComment(enum_def.doc_comment, code_ptr, nullptr); BeginEnum(enum_def.name, code_ptr); - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); - ++it) { + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { auto &ev = **it; GenComment(ev.doc_comment, code_ptr, nullptr); - EnumMember(ev, code_ptr); + EnumMember(enum_def, ev, code_ptr); } std::string &code = *code_ptr; code += "\n"; code += Indent + "private static $names = array(\n"; - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); - ++it) { + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { auto &ev = **it; code += Indent + Indent + enum_def.name + "::" + ev.name + "=>" + "\"" + ev.name + "\",\n"; } diff --git a/src/idl_gen_python.cpp b/src/idl_gen_python.cpp index fbb0805c..f2688e4e 100644 --- a/src/idl_gen_python.cpp +++ b/src/idl_gen_python.cpp @@ -112,12 +112,14 @@ class PythonGenerator : public BaseGenerator { } // A single enum member. - void EnumMember(const EnumVal ev, std::string *code_ptr) { + void EnumMember(const EnumDef &enum_def, const EnumVal &ev, + std::string *code_ptr) { std::string &code = *code_ptr; code += Indent; code += NormalizedName(ev); code += " = "; code += NumToString(ev.value) + "\n"; + (void)enum_def; } // End enum code. @@ -589,11 +591,10 @@ class PythonGenerator : public BaseGenerator { GenComment(enum_def.doc_comment, code_ptr, nullptr, "# "); BeginEnum(NormalizedName(enum_def), code_ptr); - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); - ++it) { + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { auto &ev = **it; GenComment(ev.doc_comment, code_ptr, nullptr, "# "); - EnumMember(ev, code_ptr); + EnumMember(enum_def, ev, code_ptr); } EndEnum(code_ptr); } diff --git a/src/idl_gen_rust.cpp b/src/idl_gen_rust.cpp index e8ecbbc4..23fd34a7 100644 --- a/src/idl_gen_rust.cpp +++ b/src/idl_gen_rust.cpp @@ -295,7 +295,7 @@ class RustGenerator : public BaseGenerator { // structs, and tables) and output them to a single file. bool generate() { code_.Clear(); - code_ += "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n"; + code_ += "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n"; assert(!cur_name_space_); @@ -591,8 +591,7 @@ class RustGenerator : public BaseGenerator { int64_t anyv = 0; const EnumVal *minv = nullptr, *maxv = nullptr; - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); - ++it) { + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { const auto &ev = **it; GenComment(ev.doc_comment, " "); @@ -655,15 +654,14 @@ class RustGenerator : public BaseGenerator { code_ += ""; // Generate an array of all enumeration values. - auto num_fields = NumToString(enum_def.vals.vec.size()); + auto num_fields = NumToString(enum_def.size()); code_ += "#[allow(non_camel_case_types)]"; code_ += "const ENUM_VALUES_{{ENUM_NAME_CAPS}}:[{{ENUM_NAME}}; " + num_fields + "] = ["; - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); - ++it) { + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { const auto &ev = **it; auto value = GetEnumValUse(enum_def, ev); - auto suffix = *it != enum_def.vals.vec.back() ? "," : ""; + auto suffix = *it != enum_def.Vals().back() ? "," : ""; code_ += " " + value + suffix; } code_ += "];"; @@ -684,8 +682,8 @@ class RustGenerator : public BaseGenerator { code_ += "const ENUM_NAMES_{{ENUM_NAME_CAPS}}:[&'static str; " + NumToString(range) + "] = ["; - auto val = enum_def.vals.vec.front()->value; - for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); + auto val = enum_def.Vals().front()->value; + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { const auto &ev = **it; while (val++ != ev.value) { code_ += " \"\","; } @@ -698,14 +696,14 @@ class RustGenerator : public BaseGenerator { code_ += "pub fn enum_name_{{ENUM_NAME_SNAKE}}(e: {{ENUM_NAME}}) -> " "&'static str {"; - code_ += " let index: usize = e as usize\\"; + code_ += " let index = e as {{BASE_TYPE}}\\"; if (enum_def.vals.vec.front()->value) { auto vals = GetEnumValUse(enum_def, *enum_def.vals.vec.front()); - code_ += " - " + vals + " as usize\\"; + code_ += " - " + vals + " as {{BASE_TYPE}}\\"; } code_ += ";"; - code_ += " ENUM_NAMES_{{ENUM_NAME_CAPS}}[index]"; + code_ += " ENUM_NAMES_{{ENUM_NAME_CAPS}}[index as usize]"; code_ += "}"; code_ += ""; } @@ -1317,7 +1315,7 @@ class RustGenerator : public BaseGenerator { code_.SetValue("FIELD_NAME", Name(field)); - for (auto u_it = u->vals.vec.begin(); u_it != u->vals.vec.end(); ++u_it) { + for (auto u_it = u->Vals().begin(); u_it != u->Vals().end(); ++u_it) { auto &ev = **u_it; if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; } diff --git a/src/idl_gen_text.cpp b/src/idl_gen_text.cpp index fb75a795..4c61ff99 100644 --- a/src/idl_gen_text.cpp +++ b/src/idl_gen_text.cpp @@ -263,6 +263,23 @@ static bool GenStruct(const StructDef &struct_def, const Table *table, } // Generate a text representation of a flatbuffer in JSON format. +bool GenerateTextFromTable(const Parser &parser, const void *table, + const std::string &table_name, std::string *_text) { + auto struct_def = parser.LookupStruct(table_name); + if (struct_def == nullptr) { + return false; + } + auto text = *_text; + text.reserve(1024); // Reduce amount of inevitable reallocs. + auto root = static_cast<const Table *>(table); + if (!GenStruct(*struct_def, root, 0, parser.opts, _text)) { + return false; + } + text += NewLine(parser.opts); + return true; +} + +// Generate a text representation of a flatbuffer in JSON format. bool GenerateText(const Parser &parser, const void *flatbuffer, std::string *_text) { std::string &text = *_text; diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index 583538fa..e26aa550 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -99,8 +99,10 @@ void DeserializeDoc( std::vector<std::string> &doc, } void Parser::Message(const std::string &msg) { - error_ = file_being_parsed_.length() ? AbsolutePath(file_being_parsed_) : ""; + if (!error_.empty()) error_ += "\n"; // log all warnings and errors + error_ += file_being_parsed_.length() ? AbsolutePath(file_being_parsed_) : ""; // clang-format off + #ifdef _WIN32 // MSVC alike error_ += "(" + NumToString(line_) + ", " + NumToString(CursorPosition()) + ")"; @@ -135,21 +137,21 @@ template<typename F> CheckedError Parser::Recurse(F f) { return ce; } -CheckedError Parser::InvalidNumber(const char *number, const std::string &msg) { - return Error("invalid number: \"" + std::string(number) + "\"" + msg); +template<typename T> std::string TypeToIntervalString() { + return "[" + NumToString((flatbuffers::numeric_limits<T>::lowest)()) + "; " + + NumToString((flatbuffers::numeric_limits<T>::max)()) + "]"; } -// atot: templated version of atoi/atof: convert a string to an instance of T. + +// atot: template version of atoi/atof: convert a string to an instance of T. template<typename T> inline CheckedError atot(const char *s, Parser &parser, T *val) { auto done = StringToNumber(s, val); if (done) return NoError(); - - return parser.InvalidNumber( - s, (0 == *val) - ? "" - : (", constant does not fit [" + - NumToString(flatbuffers::numeric_limits<T>::lowest()) + "; " + - NumToString(flatbuffers::numeric_limits<T>::max()) + "]")); + if (0 == *val) + return parser.Error("invalid number: \"" + std::string(s) + "\""); + else + return parser.Error("invalid number: \"" + std::string(s) + "\"" + + ", constant does not fit " + TypeToIntervalString<T>()); } template<> inline CheckedError atot<Offset<void>>(const char *s, Parser &parser, @@ -668,11 +670,11 @@ CheckedError Parser::ParseField(StructDef &struct_def) { if (token_ == '=') { NEXT(); + ECHECK(ParseSingleValue(&field->name, field->value, true)); if (!IsScalar(type.base_type) || (struct_def.fixed && field->value.constant != "0")) return Error( "default values currently only supported for scalars in tables"); - ECHECK(ParseSingleValue(&field->name, field->value, true)); } if (type.enum_def && !type.enum_def->is_union && @@ -1254,7 +1256,7 @@ CheckedError Parser::ParseNestedFlatbuffer(Value &val, FieldDef *field, nested_parser.enums_.vec.clear(); if (!ok) { - ECHECK(Error(nested_parser.error_)); + ECHECK(Error(nested_parser.error_)); } // Force alignment for nested flatbuffer builder_.ForceVectorAlignment(nested_parser.builder_.GetSize(), sizeof(uint8_t), @@ -1334,8 +1336,9 @@ CheckedError Parser::TryTypedValue(const std::string *name, int dtoken, return NoError(); } -CheckedError Parser::ParseEnumFromString(Type &type, int64_t *result) { - *result = 0; +CheckedError Parser::ParseEnumFromString(const Type &type, + std::string *result) { + int64_t i64 = 0; // Parse one or more enum identifiers, separated by spaces. const char *next = attribute_.c_str(); do { @@ -1353,7 +1356,7 @@ CheckedError Parser::ParseEnumFromString(Type &type, int64_t *result) { if (!enum_val) return Error("unknown enum value: " + word + ", for enum: " + type.enum_def->name); - *result |= enum_val->value; + i64 |= enum_val->value; } else { // No enum type, probably integral field. if (!IsInteger(type.base_type)) return Error("not a valid value for this field: " + word); @@ -1367,9 +1370,10 @@ CheckedError Parser::ParseEnumFromString(Type &type, int64_t *result) { if (!enum_def) return Error("unknown enum: " + enum_def_str); auto enum_val = enum_def->vals.Lookup(enum_val_str); if (!enum_val) return Error("unknown enum value: " + enum_val_str); - *result |= enum_val->value; + i64 |= enum_val->value; } } while (*next); + *result = NumToString(i64); return NoError(); } @@ -1503,9 +1507,7 @@ CheckedError Parser::ParseSingleValue(const std::string *name, Value &e, // Enum can have only true integer base type. if (!match && IsInteger(e.type.base_type) && !IsBool(e.type.base_type) && IsIdentifierStart(*attribute_.c_str())) { - int64_t val; - ECHECK(ParseEnumFromString(e.type, &val)); - e.constant = NumToString(val); + ECHECK(ParseEnumFromString(e.type, &e.constant)); NEXT(); match = true; } @@ -2035,10 +2037,18 @@ CheckedError Parser::ParseProtoDecl() { // Temp: remove any duplicates, as .fbs files can't handle them. for (auto it = v.begin(); it != v.end();) { - if (it != v.begin() && it[0]->value == it[-1]->value) + if (it != v.begin() && it[0]->value == it[-1]->value) { + auto ref = it[-1]; + auto ev = it[0]; + for (auto dit = enum_def->vals.dict.begin(); + dit != enum_def->vals.dict.end(); ++dit) { + if (dit->second == ev) dit->second = ref; // reassign + } + delete ev; // delete enum value it = v.erase(it); - else + } else { ++it; + } } } else if (IsIdent("syntax")) { // Skip these. NEXT(); @@ -2482,8 +2492,8 @@ CheckedError Parser::ParseRoot(const char *source, const char **include_paths, for (auto it = enums_.vec.begin(); it != enums_.vec.end(); ++it) { auto &enum_def = **it; if (enum_def.is_union) { - for (auto val_it = enum_def.vals.vec.begin(); - val_it != enum_def.vals.vec.end(); ++val_it) { + for (auto val_it = enum_def.Vals().begin(); + val_it != enum_def.Vals().end(); ++val_it) { auto &val = **val_it; if (!SupportsAdvancedUnionFeatures() && val.union_type.struct_def && val.union_type.struct_def->fixed) @@ -3192,7 +3202,7 @@ std::string Parser::ConformTo(const Parser &base) { enum_def.defined_namespace->GetFullyQualifiedName(enum_def.name); auto enum_def_base = base.enums_.Lookup(qualified_name); if (!enum_def_base) continue; - for (auto evit = enum_def.vals.vec.begin(); evit != enum_def.vals.vec.end(); + for (auto evit = enum_def.Vals().begin(); evit != enum_def.Vals().end(); ++evit) { auto &enum_val = **evit; auto enum_val_base = enum_def_base->vals.Lookup(enum_val.name); diff --git a/tests/generate_code.sh b/tests/generate_code.sh index 5d6b7ce4..40373a34 100755 --- a/tests/generate_code.sh +++ b/tests/generate_code.sh @@ -17,7 +17,7 @@ set -e ../flatc --cpp --java --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --grpc --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json ../flatc --cpp --java --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs -../flatc --cpp --java --js --ts --php --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs +../flatc --cpp --java --csharp --js --ts --php --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs ../flatc -b --schema --bfbs-comments --bfbs-builtins -I include_test monster_test.fbs ../flatc --jsonschema --schema -I include_test monster_test.fbs ../flatc --cpp --java --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes monster_extra.fbs || goto FAIL diff --git a/tests/monster_test_generated.h b/tests/monster_test_generated.h index f98e86b7..3deadd93 100644 --- a/tests/monster_test_generated.h +++ b/tests/monster_test_generated.h @@ -209,10 +209,11 @@ struct AnyUnion { #ifndef FLATBUFFERS_CPP98_STL template <typename T> void Set(T&& val) { + using RT = typename std::remove_reference<T>::type; Reset(); - type = AnyTraits<typename T::TableType>::enum_value; + type = AnyTraits<typename RT::TableType>::enum_value; if (type != Any_NONE) { - value = new T(std::forward<T>(val)); + value = new RT(std::forward<T>(val)); } } #endif // FLATBUFFERS_CPP98_STL @@ -350,10 +351,11 @@ struct AnyUniqueAliasesUnion { #ifndef FLATBUFFERS_CPP98_STL template <typename T> void Set(T&& val) { + using RT = typename std::remove_reference<T>::type; Reset(); - type = AnyUniqueAliasesTraits<typename T::TableType>::enum_value; + type = AnyUniqueAliasesTraits<typename RT::TableType>::enum_value; if (type != AnyUniqueAliases_NONE) { - value = new T(std::forward<T>(val)); + value = new RT(std::forward<T>(val)); } } #endif // FLATBUFFERS_CPP98_STL @@ -540,6 +542,9 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(2) Test FLATBUFFERS_FINAL_CLASS { int8_t padding0__; public: + static const flatbuffers::TypeTable *MiniReflectTypeTable() { + return TestTypeTable(); + } Test() { memset(static_cast<void *>(this), 0, sizeof(Test)); } @@ -588,6 +593,9 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Vec3 FLATBUFFERS_FINAL_CLASS { int16_t padding2__; public: + static const flatbuffers::TypeTable *MiniReflectTypeTable() { + return Vec3TypeTable(); + } Vec3() { memset(static_cast<void *>(this), 0, sizeof(Vec3)); } @@ -665,6 +673,9 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Ability FLATBUFFERS_FINAL_CLASS { uint32_t distance_; public: + static const flatbuffers::TypeTable *MiniReflectTypeTable() { + return AbilityTypeTable(); + } Ability() { memset(static_cast<void *>(this), 0, sizeof(Ability)); } diff --git a/tests/monster_test_generated.rs b/tests/monster_test_generated.rs index 558985ef..6a0f37a5 100644 --- a/tests/monster_test_generated.rs +++ b/tests/monster_test_generated.rs @@ -227,8 +227,8 @@ const ENUM_NAMES_COLOR:[&'static str; 8] = [ ]; pub fn enum_name_color(e: Color) -> &'static str { - let index: usize = e as usize - Color::Red as usize; - ENUM_NAMES_COLOR[index] + let index = e as i8 - Color::Red as i8; + ENUM_NAMES_COLOR[index as usize] } #[allow(non_camel_case_types)] @@ -293,8 +293,8 @@ const ENUM_NAMES_ANY:[&'static str; 4] = [ ]; pub fn enum_name_any(e: Any) -> &'static str { - let index: usize = e as usize; - ENUM_NAMES_ANY[index] + let index = e as u8; + ENUM_NAMES_ANY[index as usize] } pub struct AnyUnionTableOffset {} @@ -360,8 +360,8 @@ const ENUM_NAMES_ANY_UNIQUE_ALIASES:[&'static str; 4] = [ ]; pub fn enum_name_any_unique_aliases(e: AnyUniqueAliases) -> &'static str { - let index: usize = e as usize; - ENUM_NAMES_ANY_UNIQUE_ALIASES[index] + let index = e as u8; + ENUM_NAMES_ANY_UNIQUE_ALIASES[index as usize] } pub struct AnyUniqueAliasesUnionTableOffset {} @@ -427,8 +427,8 @@ const ENUM_NAMES_ANY_AMBIGUOUS_ALIASES:[&'static str; 4] = [ ]; pub fn enum_name_any_ambiguous_aliases(e: AnyAmbiguousAliases) -> &'static str { - let index: usize = e as usize; - ENUM_NAMES_ANY_AMBIGUOUS_ALIASES[index] + let index = e as u8; + ENUM_NAMES_ANY_AMBIGUOUS_ALIASES[index as usize] } pub struct AnyAmbiguousAliasesUnionTableOffset {} diff --git a/tests/namespace_test/namespace_test1_generated.h b/tests/namespace_test/namespace_test1_generated.h index 12b344d1..239e6e4b 100644 --- a/tests/namespace_test/namespace_test1_generated.h +++ b/tests/namespace_test/namespace_test1_generated.h @@ -56,6 +56,9 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) StructInNestedNS FLATBUFFERS_FINAL_CLASS int32_t b_; public: + static const flatbuffers::TypeTable *MiniReflectTypeTable() { + return StructInNestedNSTypeTable(); + } StructInNestedNS() { memset(static_cast<void *>(this), 0, sizeof(StructInNestedNS)); } diff --git a/tests/namespace_test/namespace_test1_generated.rs b/tests/namespace_test/namespace_test1_generated.rs index 3ffcde4c..ab302991 100644 --- a/tests/namespace_test/namespace_test1_generated.rs +++ b/tests/namespace_test/namespace_test1_generated.rs @@ -84,8 +84,8 @@ const ENUM_NAMES_ENUM_IN_NESTED_NS:[&'static str; 3] = [ ]; pub fn enum_name_enum_in_nested_ns(e: EnumInNestedNS) -> &'static str { - let index: usize = e as usize; - ENUM_NAMES_ENUM_IN_NESTED_NS[index] + let index = e as i8; + ENUM_NAMES_ENUM_IN_NESTED_NS[index as usize] } // struct StructInNestedNS, aligned to 4 diff --git a/tests/prototest/test.golden b/tests/prototest/test.golden index ad59295a..cf861b9b 100644 --- a/tests/prototest/test.golden +++ b/tests/prototest/test.golden @@ -4,6 +4,7 @@ namespace proto.test; /// Enum doc comment. enum ProtoEnum : int { + NUL = 0, FOO = 1, /// Enum 2nd value doc comment misaligned. BAR = 5, diff --git a/tests/prototest/test.proto b/tests/prototest/test.proto index cae1f3cf..45ce6c0e 100644 --- a/tests/prototest/test.proto +++ b/tests/prototest/test.proto @@ -7,9 +7,15 @@ package proto.test; /// Enum doc comment. enum ProtoEnum { + option allow_alias = true; + NUL = 0; FOO = 1; -/// Enum 2nd value doc comment misaligned. + /// Enum 2nd value doc comment misaligned. BAR = 5; + // Aliases + FOO_A1 = 1; + BAR_A1 = 5; + FOO_A2 = 1; } /// 2nd table doc comment with diff --git a/tests/prototest/test_union.golden b/tests/prototest/test_union.golden index 33fa0849..18270eb5 100644 --- a/tests/prototest/test_union.golden +++ b/tests/prototest/test_union.golden @@ -4,6 +4,7 @@ namespace proto.test; /// Enum doc comment. enum ProtoEnum : int { + NUL = 0, FOO = 1, /// Enum 2nd value doc comment misaligned. BAR = 5, diff --git a/tests/test.cpp b/tests/test.cpp index 6da1dff9..e0232300 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -894,6 +894,17 @@ void MiniReflectFlatBuffersTest(uint8_t *flatbuf) { "test5: [ { a: 10, b: 20 }, { a: 30, b: 40 } ], " "vector_of_enums: [ Blue, Green ] " "}"); + + Test test(16, 32); + Vec3 vec(1,2,3, 1.5, Color_Red, test); + flatbuffers::FlatBufferBuilder vec_builder; + vec_builder.Finish(vec_builder.CreateStruct(vec)); + auto vec_buffer = vec_builder.Release(); + auto vec_str = flatbuffers::FlatBufferToString(vec_buffer.data(), + Vec3::MiniReflectTypeTable()); + TEST_EQ_STR( + vec_str.c_str(), + "{ x: 1.0, y: 2.0, z: 3.0, test1: 1.5, test2: Red, test3: { a: 16, b: 32 } }"); } // Parse a .proto schema, output as .fbs @@ -1264,6 +1275,7 @@ void ErrorTest() { TestError("table Y {} table X { Y:int; }", "same as table"); TestError("struct X { Y:string; }", "only scalar"); TestError("table X { Y:string = \"\"; }", "default values"); + TestError("struct X { a:uint = 42; }", "default values"); TestError("enum Y:byte { Z = 1 } table X { y:Y; }", "not part of enum"); TestError("struct X { Y:int (deprecated); }", "deprecate"); TestError("union Z { X } table X { Y:Z; } root_type X; { Y: {}, A:1 }", @@ -1305,15 +1317,20 @@ void ErrorTest() { TestError("enum X:bool { Y = true }", "must be integral"); } -template<typename T> T TestValue(const char *json, const char *type_name) { +template<typename T> +T TestValue(const char *json, const char *type_name, + const char *decls = nullptr) { flatbuffers::Parser parser; parser.builder_.ForceDefaults(true); // return defaults auto check_default = json ? false : true; if (check_default) { parser.opts.output_default_scalars_in_json = true; } // Simple schema. - std::string schema = - "table X { Y:" + std::string(type_name) + "; } root_type X;"; - TEST_EQ(parser.Parse(schema.c_str()), true); + std::string schema = std::string(decls ? decls : "") + "\n" + + "table X { Y:" + std::string(type_name) + + "; } root_type X;"; + auto schema_done = parser.Parse(schema.c_str()); + TEST_EQ_STR(parser.error_.c_str(), ""); + TEST_EQ(schema_done, true); auto done = parser.Parse(check_default ? "{}" : json); TEST_EQ_STR(parser.error_.c_str(), ""); @@ -1439,6 +1456,24 @@ void EnumOutOfRangeTest() { TestError("enum X:ulong { Y = 18446744073709551615 }", "constant does not fit"); } +void EnumValueTest() { + // json: "{ Y:0 }", schema: table X { Y : "E"} + // 0 in enum (V=0) E then Y=0 is valid. + TEST_EQ(TestValue<int>("{ Y:0 }", "E", "enum E:int { V }"), 0); + TEST_EQ(TestValue<int>("{ Y:V }", "E", "enum E:int { V }"), 0); + // A default value of Y is 0. + TEST_EQ(TestValue<int>("{ }", "E", "enum E:int { V }"), 0); + TEST_EQ(TestValue<int>("{ Y:5 }", "E=V", "enum E:int { V=5 }"), 5); + // Generate json with defaults and check. + TEST_EQ(TestValue<int>(nullptr, "E=V", "enum E:int { V=5 }"), 5); + // 5 in enum + TEST_EQ(TestValue<int>("{ Y:5 }", "E", "enum E:int { Z, V=5 }"), 5); + TEST_EQ(TestValue<int>("{ Y:5 }", "E=V", "enum E:int { Z, V=5 }"), 5); + // Generate json with defaults and check. + TEST_EQ(TestValue<int>(nullptr, "E", "enum E:int { Z, V=5 }"), 0); + TEST_EQ(TestValue<int>(nullptr, "E=V", "enum E:int { Z, V=5 }"), 5); +} + void IntegerOutOfRangeTest() { TestError("table T { F:byte; } root_type T; { F:128 }", "constant does not fit"); @@ -1702,6 +1737,53 @@ void InvalidFloatTest() { TestError("table T { F:float; } root_type T; { F:null }", invalid_msg); } +void GenerateTableTextTest() { + std::string schemafile; + std::string jsonfile; + bool ok = + flatbuffers::LoadFile((test_data_path + "monster_test.fbs").c_str(), + false, &schemafile) && + flatbuffers::LoadFile((test_data_path + "monsterdata_test.json").c_str(), + false, &jsonfile); + TEST_EQ(ok, true); + auto include_test_path = + flatbuffers::ConCatPathFileName(test_data_path, "include_test"); + const char *include_directories[] = {test_data_path.c_str(), + include_test_path.c_str(), nullptr}; + flatbuffers::IDLOptions opt; + opt.indent_step = -1; + flatbuffers::Parser parser(opt); + ok = parser.Parse(schemafile.c_str(), include_directories) && + parser.Parse(jsonfile.c_str(), include_directories); + TEST_EQ(ok, true); + // Test root table + const Monster *monster = GetMonster(parser.builder_.GetBufferPointer()); + std::string jsongen; + auto result = GenerateTextFromTable(parser, monster, "MyGame.Example.Monster", + &jsongen); + TEST_EQ(result, true); + // Test sub table + const Vec3 *pos = monster->pos(); + jsongen.clear(); + result = GenerateTextFromTable(parser, pos, "MyGame.Example.Vec3", &jsongen); + TEST_EQ(result, true); + TEST_EQ_STR( + jsongen.c_str(), + "{x: 1.0,y: 2.0,z: 3.0,test1: 3.0,test2: \"Green\",test3: {a: 5,b: 6}}"); + const Test &test3 = pos->test3(); + jsongen.clear(); + result = + GenerateTextFromTable(parser, &test3, "MyGame.Example.Test", &jsongen); + TEST_EQ(result, true); + TEST_EQ_STR(jsongen.c_str(), "{a: 5,b: 6}"); + const Test *test4 = monster->test4()->Get(0); + jsongen.clear(); + result = + GenerateTextFromTable(parser, test4, "MyGame.Example.Test", &jsongen); + TEST_EQ(result, true); + TEST_EQ_STR(jsongen.c_str(), "{a: 10,b: 20}"); +} + template<typename T> void NumericUtilsTestInteger(const char *lower, const char *upper) { T x; @@ -2567,6 +2649,7 @@ int FlatBufferTests() { ParseProtoTest(); UnionVectorTest(); LoadVerifyBinaryTest(); + GenerateTableTextTest(); #endif // clang-format on @@ -2575,6 +2658,7 @@ int FlatBufferTests() { ErrorTest(); ValueTest(); + EnumValueTest(); EnumStringsTest(); EnumNamesTest(); EnumOutOfRangeTest(); diff --git a/tests/test_assert.cpp b/tests/test_assert.cpp index 804663cd..ccbce235 100644 --- a/tests/test_assert.cpp +++ b/tests/test_assert.cpp @@ -4,6 +4,7 @@ #ifdef _MSC_VER # include <crtdbg.h> +# include <windows.h> #endif int testing_fails = 0; @@ -43,15 +44,19 @@ void InitTestEngine(TestFailEventListener listener) { // clang-format off #ifdef _MSC_VER - // Send all reports to STDOUT. + // By default, send all reports to STDOUT to prevent CI hangs. + // Enable assert report box [Abort|Retry|Ignore] if a debugger is present. + const int dbg_mode = (_CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG) | + (IsDebuggerPresent() ? _CRTDBG_MODE_WNDW : 0); + (void)dbg_mode; // release mode fix // CrtDebug reports to _CRT_WARN channel. - _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); + _CrtSetReportMode(_CRT_WARN, dbg_mode); _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT); // The assert from <assert.h> reports to _CRT_ERROR channel - _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); + _CrtSetReportMode(_CRT_ERROR, dbg_mode); _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT); // Internal CRT assert channel? - _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); + _CrtSetReportMode(_CRT_ASSERT, dbg_mode); _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT); #endif diff --git a/tests/union_vector/Attacker.cs b/tests/union_vector/Attacker.cs index c81e8d59..7f20fff8 100644 --- a/tests/union_vector/Attacker.cs +++ b/tests/union_vector/Attacker.cs @@ -15,6 +15,7 @@ public struct Attacker : IFlatbufferObject public Attacker __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } public int SwordAttackDamage { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } } + public bool MutateSwordAttackDamage(int sword_attack_damage) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutInt(o + __p.bb_pos, sword_attack_damage); return true; } else { return false; } } public static Offset<Attacker> CreateAttacker(FlatBufferBuilder builder, int sword_attack_damage = 0) { diff --git a/tests/union_vector/BookReader.cs b/tests/union_vector/BookReader.cs index 1642b81f..2cd33bfc 100644 --- a/tests/union_vector/BookReader.cs +++ b/tests/union_vector/BookReader.cs @@ -13,6 +13,7 @@ public struct BookReader : IFlatbufferObject public BookReader __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } public int BooksRead { get { return __p.bb.GetInt(__p.bb_pos + 0); } } + public void MutateBooksRead(int books_read) { __p.bb.PutInt(__p.bb_pos + 0, books_read); } public static Offset<BookReader> CreateBookReader(FlatBufferBuilder builder, int BooksRead) { builder.Prep(4, 4); diff --git a/tests/union_vector/Movie.cs b/tests/union_vector/Movie.cs index b229b4fe..6a9130a7 100644 --- a/tests/union_vector/Movie.cs +++ b/tests/union_vector/Movie.cs @@ -16,6 +16,7 @@ public struct Movie : IFlatbufferObject public Movie __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } public Character MainCharacterType { get { int o = __p.__offset(4); return o != 0 ? (Character)__p.bb.Get(o + __p.bb_pos) : Character.NONE; } } + public bool MutateMainCharacterType(Character main_character_type) { int o = __p.__offset(4); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)main_character_type); return true; } else { return false; } } public TTable? MainCharacter<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(6); return o != 0 ? (TTable?)__p.__union<TTable>(o) : null; } public Character CharactersType(int j) { int o = __p.__offset(8); return o != 0 ? (Character)__p.bb.Get(__p.__vector(o) + j * 1) : (Character)0; } public int CharactersTypeLength { get { int o = __p.__offset(8); return o != 0 ? __p.__vector_len(o) : 0; } } @@ -25,7 +26,8 @@ public struct Movie : IFlatbufferObject public ArraySegment<byte>? GetCharactersTypeBytes() { return __p.__vector_as_arraysegment(8); } #endif public Character[] GetCharactersTypeArray() { return __p.__vector_as_array<Character>(8); } - public TTable? Characters<TTable>(int j) where TTable : struct, IFlatbufferObject { int o = __p.__offset(10); return o != 0 ? (TTable?)__p.__union<TTable>(__p.__vector(o) + j * 4) : null; } + public bool MutateCharactersType(int j, Character characters_type) { int o = __p.__offset(8); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, (byte)characters_type); return true; } else { return false; } } + public TTable? Characters<TTable>(int j) where TTable : struct, IFlatbufferObject { int o = __p.__offset(10); return o != 0 ? (TTable?)__p.__union<TTable>(__p.__vector(o) + j * 4 - __p.bb_pos) : null; } public int CharactersLength { get { int o = __p.__offset(10); return o != 0 ? __p.__vector_len(o) : 0; } } public static Offset<Movie> CreateMovie(FlatBufferBuilder builder, diff --git a/tests/union_vector/Rapunzel.cs b/tests/union_vector/Rapunzel.cs index 4928f5d4..f95f1004 100644 --- a/tests/union_vector/Rapunzel.cs +++ b/tests/union_vector/Rapunzel.cs @@ -13,6 +13,7 @@ public struct Rapunzel : IFlatbufferObject public Rapunzel __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } public int HairLength { get { return __p.bb.GetInt(__p.bb_pos + 0); } } + public void MutateHairLength(int hair_length) { __p.bb.PutInt(__p.bb_pos + 0, hair_length); } public static Offset<Rapunzel> CreateRapunzel(FlatBufferBuilder builder, int HairLength) { builder.Prep(4, 4); diff --git a/tests/union_vector/union_vector_generated.h b/tests/union_vector/union_vector_generated.h index 962c98b9..757a9584 100644 --- a/tests/union_vector/union_vector_generated.h +++ b/tests/union_vector/union_vector_generated.h @@ -197,6 +197,9 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Rapunzel FLATBUFFERS_FINAL_CLASS { int32_t hair_length_; public: + static const flatbuffers::TypeTable *MiniReflectTypeTable() { + return RapunzelTypeTable(); + } Rapunzel() { memset(static_cast<void *>(this), 0, sizeof(Rapunzel)); } @@ -227,6 +230,9 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) BookReader FLATBUFFERS_FINAL_CLASS { int32_t books_read_; public: + static const flatbuffers::TypeTable *MiniReflectTypeTable() { + return BookReaderTypeTable(); + } BookReader() { memset(static_cast<void *>(this), 0, sizeof(BookReader)); } @@ -541,13 +547,13 @@ inline bool VerifyCharacter(flatbuffers::Verifier &verifier, const void *obj, Ch return verifier.VerifyTable(ptr); } case Character_Rapunzel: { - return true; + return verifier.Verify<Rapunzel>(static_cast<const uint8_t *>(obj), 0); } case Character_Belle: { - return true; + return verifier.Verify<BookReader>(static_cast<const uint8_t *>(obj), 0); } case Character_BookFan: { - return true; + return verifier.Verify<BookReader>(static_cast<const uint8_t *>(obj), 0); } case Character_Other: { auto ptr = reinterpret_cast<const flatbuffers::String *>(obj); |