Upgrade flatbuffer to 'v1.11.0'
am: fa7eaaa976

Change-Id: I9c27c2165ef53f2cfac00f39e5a09e9b1ffb470c
diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml
index 13fc184..a6e38fd 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:
diff --git a/.gitignore b/.gitignore
index 56a7f6d..b7b41ac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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 b7acbc7..119855a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -289,7 +289,7 @@
   # - 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}")
diff --git a/METADATA b/METADATA
index 79954ab..81e6cdc 100644
--- a/METADATA
+++ b/METADATA
@@ -9,10 +9,10 @@
     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 6adf8aa..4761ffc 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 66c800d..4f7bd72 100644
--- a/docs/source/Schemas.md
+++ b/docs/source/Schemas.md
@@ -324,8 +324,8 @@
     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 4291c06..e23068b 100644
--- a/docs/source/Tutorial.md
+++ b/docs/source/Tutorial.md
@@ -653,14 +653,14 @@
 
   // 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 @@
 </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 @@
 
 <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 b773fdf..832c46e 100644
--- a/docs/source/TypeScriptUsage.md
+++ b/docs/source/TypeScriptUsage.md
@@ -17,7 +17,7 @@
 ## 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 479905b..40799ae 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 1f7b236..c51348d 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 5348970..5f8731e 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 a64a587..ee8021f 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 05d666c..8299fe0 100644
--- a/include/flatbuffers/idl.h
+++ b/include/flatbuffers/idl.h
@@ -334,6 +334,8 @@
   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 @@
   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 @@
 
   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 @@
   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 @@
   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 @@
 // 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 0c970bd..4160852 100644
--- a/js/flatbuffers.js
+++ b/js/flatbuffers.js
@@ -829,7 +829,6 @@
    * @private
    */
   this.position_ = 0;
-
 };
 
 /**
@@ -842,7 +841,7 @@
   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 daf76b0..f95e754 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",
diff --git a/pom.xml b/pom.xml
index 3e91911..60bd7f5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -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 67bbd8d..32d9b1b 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
index 95a977a..061a17b 100644
--- a/samples/monster.bfbs
+++ b/samples/monster.bfbs
Binary files differ
diff --git a/samples/monster.fbs b/samples/monster.fbs
index 247b817..af22451 100644
--- a/samples/monster.fbs
+++ b/samples/monster.fbs
@@ -22,6 +22,7 @@
   color:Color = Blue;
   weapons:[Weapon];
   equipped:Equipment;
+  path:[Vec3];
 }
 
 table Weapon {
diff --git a/samples/monster_generated.h b/samples/monster_generated.h
index 84e8160..7026116 100644
--- a/samples/monster_generated.h
+++ b/samples/monster_generated.h
@@ -121,10 +121,11 @@
 #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 @@
   float z_;
 
  public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return Vec3TypeTable();
+  }
   Vec3() {
     memset(static_cast<void *>(this), 0, sizeof(Vec3));
   }
@@ -224,6 +228,7 @@
   Color color;
   std::vector<flatbuffers::unique_ptr<WeaponT>> weapons;
   EquipmentUnion equipped;
+  std::vector<Vec3> path;
   MonsterT()
       : mana(150),
         hp(100),
@@ -240,7 +245,8 @@
       (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 @@
     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 @@
   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 @@
            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 @@
   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 @@
     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 @@
     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 @@
       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 @@
   { 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 @@
   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 @@
       _color,
       _weapons,
       _equipped_type,
-      _equipped);
+      _equipped,
+      _path);
 }
 
 inline WeaponT *Weapon::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
@@ -756,7 +782,8 @@
     { 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 @@
     "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 c1a3199..409e77d 100644
--- a/samples/monster_generated.lobster
+++ b/samples/monster_generated.lobster
@@ -58,11 +58,15 @@
         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 @@
     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 0000000..1713896
--- /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 3833f3d..78e4c5b 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 @@
   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 50cb82f..268c436 100644
--- a/src/idl_gen_cpp.cpp
+++ b/src/idl_gen_cpp.cpp
@@ -785,7 +785,7 @@
                    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 @@
         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 @@
     }
     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 @@
 
     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 @@
     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 @@
       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 @@
 
       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 @@
 
     // 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 @@
         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 @@
       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 @@
         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 @@
 
     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 @@
       // 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 @@
 
       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 @@
           "{{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 @@
 
       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 @@
               "  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 @@
 
       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 @@
     // 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 fb7e0bd..2141eb3 100644
--- a/src/idl_gen_dart.cpp
+++ b/src/idl_gen_dart.cpp
@@ -251,12 +251,11 @@
         "  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 @@
     }
 
     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 @@
       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 37c6026..5a85a95 100644
--- a/src/idl_gen_fbs.cpp
+++ b/src/idl_gen_fbs.cpp
@@ -96,8 +96,7 @@
     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 5fa9b18..fe793bf 100644
--- a/src/idl_gen_general.cpp
+++ b/src/idl_gen_general.cpp
@@ -543,8 +543,7 @@
     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 @@
         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 @@
                           : 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 7a68e8a..412d1e8 100644
--- a/src/idl_gen_go.cpp
+++ b/src/idl_gen_go.cpp
@@ -153,7 +153,7 @@
   }
 
   // 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 @@
     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 @@
     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 9b7942b..fea4620 100644
--- a/src/idl_gen_js_ts.cpp
+++ b/src/idl_gen_js_ts.cpp
@@ -350,11 +350,10 @@
       }
       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 @@
         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 1883580..a0f193b 100644
--- a/src/idl_gen_json_schema.cpp
+++ b/src/idl_gen_json_schema.cpp
@@ -86,7 +86,7 @@
     }
     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 @@
           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 @@
       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 5f199e3..fe23d97 100644
--- a/src/idl_gen_lobster.cpp
+++ b/src/idl_gen_lobster.cpp
@@ -149,10 +149,10 @@
         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 @@
     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 e8ae328..b26f907 100644
--- a/src/idl_gen_lua.cpp
+++ b/src/idl_gen_lua.cpp
@@ -109,9 +109,10 @@
     }
 
     // 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 @@
       }
       code += EndFunc;
     }
-    
+
     // Begin the creator function signature.
     void BeginBuilderArgs(const StructDef &struct_def,
       std::string *code_ptr) {
@@ -497,7 +498,7 @@
             GetMemberOfVectorOfStruct(struct_def, field, code_ptr);
           }
           else {
-            GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr);            
+            GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr);
           }
           break;
         }
@@ -572,11 +573,11 @@
 
       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 3c6747e..a4b9a46 100644
--- a/src/idl_gen_php.cpp
+++ b/src/idl_gen_php.cpp
@@ -119,12 +119,14 @@
   }
 
   // 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 @@
 
     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 fbb0805..f2688e4 100644
--- a/src/idl_gen_python.cpp
+++ b/src/idl_gen_python.cpp
@@ -112,12 +112,14 @@
   }
 
   // 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 @@
 
     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 e8ecbbc..23fd34a 100644
--- a/src/idl_gen_rust.cpp
+++ b/src/idl_gen_rust.cpp
@@ -295,7 +295,7 @@
   // 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 @@
 
     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 @@
     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 @@
       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 @@
       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 @@
 
       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 fb75a79..4c61ff9 100644
--- a/src/idl_gen_text.cpp
+++ b/src/idl_gen_text.cpp
@@ -263,6 +263,23 @@
 }
 
 // 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 583538f..e26aa55 100644
--- a/src/idl_parser.cpp
+++ b/src/idl_parser.cpp
@@ -99,8 +99,10 @@
 }
 
 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 @@
   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 @@
 
   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 @@
     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 @@
   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 @@
       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 @@
       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 @@
     // 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 @@
 
     // 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 @@
   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 @@
         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 5d6b7ce..40373a3 100755
--- a/tests/generate_code.sh
+++ b/tests/generate_code.sh
@@ -17,7 +17,7 @@
 
 ../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 f98e86b..3deadd9 100644
--- a/tests/monster_test_generated.h
+++ b/tests/monster_test_generated.h
@@ -209,10 +209,11 @@
 #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 @@
 #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 @@
   int8_t padding0__;
 
  public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return TestTypeTable();
+  }
   Test() {
     memset(static_cast<void *>(this), 0, sizeof(Test));
   }
@@ -588,6 +593,9 @@
   int16_t padding2__;
 
  public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return Vec3TypeTable();
+  }
   Vec3() {
     memset(static_cast<void *>(this), 0, sizeof(Vec3));
   }
@@ -665,6 +673,9 @@
   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 558985e..6a0f37a 100644
--- a/tests/monster_test_generated.rs
+++ b/tests/monster_test_generated.rs
@@ -227,8 +227,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 @@
 ];
 
 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 @@
 ];
 
 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 @@
 ];
 
 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 12b344d..239e6e4 100644
--- a/tests/namespace_test/namespace_test1_generated.h
+++ b/tests/namespace_test/namespace_test1_generated.h
@@ -56,6 +56,9 @@
   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 3ffcde4..ab30299 100644
--- a/tests/namespace_test/namespace_test1_generated.rs
+++ b/tests/namespace_test/namespace_test1_generated.rs
@@ -84,8 +84,8 @@
 ];
 
 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 ad59295..cf861b9 100644
--- a/tests/prototest/test.golden
+++ b/tests/prototest/test.golden
@@ -4,6 +4,7 @@
 
 /// 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 cae1f3c..45ce6c0 100644
--- a/tests/prototest/test.proto
+++ b/tests/prototest/test.proto
@@ -7,9 +7,15 @@
 
 /// 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 33fa084..18270eb 100644
--- a/tests/prototest/test_union.golden
+++ b/tests/prototest/test_union.golden
@@ -4,6 +4,7 @@
 
 /// 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 6da1dff..e023230 100644
--- a/tests/test.cpp
+++ b/tests/test.cpp
@@ -894,6 +894,17 @@
       "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 @@
   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 @@
   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 @@
   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 @@
   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 @@
     ParseProtoTest();
     UnionVectorTest();
     LoadVerifyBinaryTest();
+    GenerateTableTextTest();
   #endif
   // clang-format on
 
@@ -2575,6 +2658,7 @@
 
   ErrorTest();
   ValueTest();
+  EnumValueTest();
   EnumStringsTest();
   EnumNamesTest();
   EnumOutOfRangeTest();
diff --git a/tests/test_assert.cpp b/tests/test_assert.cpp
index 804663c..ccbce23 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 @@
   // 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 c81e8d5..7f20fff 100644
--- a/tests/union_vector/Attacker.cs
+++ b/tests/union_vector/Attacker.cs
@@ -15,6 +15,7 @@
   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 1642b81..2cd33bf 100644
--- a/tests/union_vector/BookReader.cs
+++ b/tests/union_vector/BookReader.cs
@@ -13,6 +13,7 @@
   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 b229b4f..6a9130a 100644
--- a/tests/union_vector/Movie.cs
+++ b/tests/union_vector/Movie.cs
@@ -16,6 +16,7 @@
   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 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 4928f5d..f95f100 100644
--- a/tests/union_vector/Rapunzel.cs
+++ b/tests/union_vector/Rapunzel.cs
@@ -13,6 +13,7 @@
   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 962c98b..757a958 100644
--- a/tests/union_vector/union_vector_generated.h
+++ b/tests/union_vector/union_vector_generated.h
@@ -197,6 +197,9 @@
   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 @@
   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 @@
       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);