diff --git a/src/clang-format.sh b/src/clang-format.sh
new file mode 100644
index 0000000..fbce6b9
--- /dev/null
+++ b/src/clang-format.sh
@@ -0,0 +1,2 @@
+clang-format -i -style=file include/flatbuffers/* src/*.cpp tests/test.cpp samples/*.cpp grpc/src/compiler/schema_interface.h grpc/tests/*.cpp
+git checkout include/flatbuffers/reflection_generated.h
diff --git a/src/code_generators.cpp b/src/code_generators.cpp
new file mode 100644
index 0000000..52ca305
--- /dev/null
+++ b/src/code_generators.cpp
@@ -0,0 +1,292 @@
+/*
+ * Copyright 2016 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "flatbuffers/code_generators.h"
+#include <assert.h>
+#include "flatbuffers/base.h"
+#include "flatbuffers/util.h"
+
+#include <cmath>
+
+#if defined(_MSC_VER)
+#  pragma warning(push)
+#  pragma warning(disable : 4127)  // C4127: conditional expression is constant
+#endif
+
+namespace flatbuffers {
+
+void CodeWriter::operator+=(std::string text) {
+  if (!ignore_ident_ && !text.empty()) AppendIdent(stream_);
+
+  while (true) {
+    auto begin = text.find("{{");
+    if (begin == std::string::npos) { break; }
+
+    auto end = text.find("}}");
+    if (end == std::string::npos || end < begin) { break; }
+
+    // Write all the text before the first {{ into the stream.
+    stream_.write(text.c_str(), begin);
+
+    // The key is between the {{ and }}.
+    const std::string key = text.substr(begin + 2, end - begin - 2);
+
+    // Find the value associated with the key.  If it exists, write the
+    // value into the stream, otherwise write the key itself into the stream.
+    auto iter = value_map_.find(key);
+    if (iter != value_map_.end()) {
+      const std::string &value = iter->second;
+      stream_ << value;
+    } else {
+      FLATBUFFERS_ASSERT(false && "could not find key");
+      stream_ << key;
+    }
+
+    // Update the text to everything after the }}.
+    text = text.substr(end + 2);
+  }
+  if (!text.empty() && string_back(text) == '\\') {
+    text.pop_back();
+    ignore_ident_ = true;
+    stream_ << text;
+  } else {
+    ignore_ident_ = false;
+    stream_ << text << std::endl;
+  }
+}
+
+void CodeWriter::AppendIdent(std::stringstream &stream) {
+  int lvl = cur_ident_lvl_;
+  while (lvl--) {
+    stream.write(pad_.c_str(), static_cast<std::streamsize>(pad_.size()));
+  }
+}
+
+const char *BaseGenerator::FlatBuffersGeneratedWarning() {
+  return "automatically generated by the FlatBuffers compiler,"
+         " do not modify";
+}
+
+std::string BaseGenerator::NamespaceDir(const Parser &parser,
+                                        const std::string &path,
+                                        const Namespace &ns) {
+  EnsureDirExists(path);
+  if (parser.opts.one_file) return path;
+  std::string namespace_dir = path;  // Either empty or ends in separator.
+  auto &namespaces = ns.components;
+  for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
+    namespace_dir += *it + kPathSeparator;
+    EnsureDirExists(namespace_dir);
+  }
+  return namespace_dir;
+}
+
+std::string BaseGenerator::NamespaceDir(const Namespace &ns) const {
+  return BaseGenerator::NamespaceDir(parser_, path_, ns);
+}
+
+std::string BaseGenerator::FullNamespace(const char *separator,
+                                         const Namespace &ns) {
+  std::string namespace_name;
+  auto &namespaces = ns.components;
+  for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
+    if (namespace_name.length()) namespace_name += separator;
+    namespace_name += *it;
+  }
+  return namespace_name;
+}
+
+std::string BaseGenerator::LastNamespacePart(const Namespace &ns) {
+  if (!ns.components.empty())
+    return ns.components.back();
+  else
+    return std::string("");
+}
+
+// Ensure that a type is prefixed with its namespace.
+std::string BaseGenerator::WrapInNameSpace(const Namespace *ns,
+                                           const std::string &name) const {
+  std::string qualified_name = qualifying_start_;
+  for (auto it = ns->components.begin(); it != ns->components.end(); ++it)
+    qualified_name += *it + qualifying_separator_;
+  return qualified_name + name;
+}
+
+std::string BaseGenerator::WrapInNameSpace(const Definition &def) const {
+  return WrapInNameSpace(def.defined_namespace, def.name);
+}
+
+std::string BaseGenerator::GetNameSpace(const Definition &def) const {
+  const Namespace *ns = def.defined_namespace;
+  if (CurrentNameSpace() == ns) return "";
+  std::string qualified_name = qualifying_start_;
+  for (auto it = ns->components.begin(); it != ns->components.end(); ++it) {
+    qualified_name += *it;
+    if ((it + 1) != ns->components.end()) {
+      qualified_name += qualifying_separator_;
+    }
+  }
+
+  return qualified_name;
+}
+
+// Generate a documentation comment, if available.
+void GenComment(const std::vector<std::string> &dc, std::string *code_ptr,
+                const CommentConfig *config, const char *prefix) {
+  if (dc.begin() == dc.end()) {
+    // Don't output empty comment blocks with 0 lines of comment content.
+    return;
+  }
+
+  std::string &code = *code_ptr;
+  if (config != nullptr && config->first_line != nullptr) {
+    code += std::string(prefix) + std::string(config->first_line) + "\n";
+  }
+  std::string line_prefix =
+      std::string(prefix) +
+      ((config != nullptr && config->content_line_prefix != nullptr)
+           ? config->content_line_prefix
+           : "///");
+  for (auto it = dc.begin(); it != dc.end(); ++it) {
+    code += line_prefix + *it + "\n";
+  }
+  if (config != nullptr && config->last_line != nullptr) {
+    code += std::string(prefix) + std::string(config->last_line) + "\n";
+  }
+}
+
+template<typename T>
+std::string FloatConstantGenerator::GenFloatConstantImpl(
+    const FieldDef &field) const {
+  const auto &constant = field.value.constant;
+  T v;
+  auto done = StringToNumber(constant.c_str(), &v);
+  FLATBUFFERS_ASSERT(done);
+  if (done) {
+#if (!defined(_MSC_VER) || (_MSC_VER >= 1800))
+    if (std::isnan(v)) return NaN(v);
+    if (std::isinf(v)) return Inf(v);
+#endif
+    return Value(v, constant);
+  }
+  return "#";  // compile time error
+}
+
+std::string FloatConstantGenerator::GenFloatConstant(
+    const FieldDef &field) const {
+  switch (field.value.type.base_type) {
+    case BASE_TYPE_FLOAT: return GenFloatConstantImpl<float>(field);
+    case BASE_TYPE_DOUBLE: return GenFloatConstantImpl<double>(field);
+    default: {
+      FLATBUFFERS_ASSERT(false);
+      return "INVALID_BASE_TYPE";
+    }
+  };
+}
+
+TypedFloatConstantGenerator::TypedFloatConstantGenerator(
+    const char *double_prefix, const char *single_prefix,
+    const char *nan_number, const char *pos_inf_number,
+    const char *neg_inf_number)
+    : double_prefix_(double_prefix),
+      single_prefix_(single_prefix),
+      nan_number_(nan_number),
+      pos_inf_number_(pos_inf_number),
+      neg_inf_number_(neg_inf_number) {}
+
+std::string TypedFloatConstantGenerator::MakeNaN(
+    const std::string &prefix) const {
+  return prefix + nan_number_;
+}
+std::string TypedFloatConstantGenerator::MakeInf(
+    bool neg, const std::string &prefix) const {
+  if (neg)
+    return !neg_inf_number_.empty() ? (prefix + neg_inf_number_)
+                                    : ("-" + prefix + pos_inf_number_);
+  else
+    return prefix + pos_inf_number_;
+}
+
+std::string TypedFloatConstantGenerator::Value(double v,
+                                               const std::string &src) const {
+  (void)v;
+  return src;
+}
+
+std::string TypedFloatConstantGenerator::Inf(double v) const {
+  return MakeInf(v < 0, double_prefix_);
+}
+
+std::string TypedFloatConstantGenerator::NaN(double v) const {
+  (void)v;
+  return MakeNaN(double_prefix_);
+}
+
+std::string TypedFloatConstantGenerator::Value(float v,
+                                               const std::string &src) const {
+  (void)v;
+  return src + "f";
+}
+
+std::string TypedFloatConstantGenerator::Inf(float v) const {
+  return MakeInf(v < 0, single_prefix_);
+}
+
+std::string TypedFloatConstantGenerator::NaN(float v) const {
+  (void)v;
+  return MakeNaN(single_prefix_);
+}
+
+SimpleFloatConstantGenerator::SimpleFloatConstantGenerator(
+    const char *nan_number, const char *pos_inf_number,
+    const char *neg_inf_number)
+    : nan_number_(nan_number),
+      pos_inf_number_(pos_inf_number),
+      neg_inf_number_(neg_inf_number) {}
+
+std::string SimpleFloatConstantGenerator::Value(double v,
+                                                const std::string &src) const {
+  (void)v;
+  return src;
+}
+
+std::string SimpleFloatConstantGenerator::Inf(double v) const {
+  return (v < 0) ? neg_inf_number_ : pos_inf_number_;
+}
+
+std::string SimpleFloatConstantGenerator::NaN(double v) const {
+  (void)v;
+  return nan_number_;
+}
+
+std::string SimpleFloatConstantGenerator::Value(float v,
+                                                const std::string &src) const {
+  return this->Value(static_cast<double>(v), src);
+}
+
+std::string SimpleFloatConstantGenerator::Inf(float v) const {
+  return this->Inf(static_cast<double>(v));
+}
+
+std::string SimpleFloatConstantGenerator::NaN(float v) const {
+  return this->NaN(static_cast<double>(v));
+}
+
+}  // namespace flatbuffers
+
+#if defined(_MSC_VER)
+#  pragma warning(pop)
+#endif
diff --git a/src/flatc.cpp b/src/flatc.cpp
new file mode 100644
index 0000000..e1236bd
--- /dev/null
+++ b/src/flatc.cpp
@@ -0,0 +1,489 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "flatbuffers/flatc.h"
+
+#include <list>
+
+namespace flatbuffers {
+
+const char *FLATC_VERSION() { return FLATBUFFERS_VERSION(); }
+
+void FlatCompiler::ParseFile(
+    flatbuffers::Parser &parser, const std::string &filename,
+    const std::string &contents,
+    std::vector<const char *> &include_directories) const {
+  auto local_include_directory = flatbuffers::StripFileName(filename);
+  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())) {
+    Error(parser.error_, false, false);
+  }
+  if (!parser.error_.empty()) { Warn(parser.error_, false); }
+  include_directories.pop_back();
+  include_directories.pop_back();
+}
+
+void FlatCompiler::LoadBinarySchema(flatbuffers::Parser &parser,
+                                    const std::string &filename,
+                                    const std::string &contents) {
+  if (!parser.Deserialize(reinterpret_cast<const uint8_t *>(contents.c_str()),
+      contents.size())) {
+    Error("failed to load binary schema: " + filename, false, false);
+  }
+}
+
+void FlatCompiler::Warn(const std::string &warn, bool show_exe_name) const {
+  params_.warn_fn(this, warn, show_exe_name);
+}
+
+void FlatCompiler::Error(const std::string &err, bool usage,
+                         bool show_exe_name) const {
+  params_.error_fn(this, err, usage, show_exe_name);
+}
+
+std::string FlatCompiler::GetUsageString(const char *program_name) const {
+  std::stringstream ss;
+  ss << "Usage: " << program_name << " [OPTION]... FILE... [-- FILE...]\n";
+  for (size_t i = 0; i < params_.num_generators; ++i) {
+    const Generator &g = params_.generators[i];
+
+    std::stringstream full_name;
+    full_name << std::setw(12) << std::left << g.generator_opt_long;
+    const char *name = g.generator_opt_short ? g.generator_opt_short : "  ";
+    const char *help = g.generator_help;
+
+    ss << "  " << full_name.str() << " " << name << "    " << help << ".\n";
+  }
+  // clang-format off
+  ss <<
+    "  -o PATH            Prefix PATH to all generated files.\n"
+    "  -I PATH            Search for includes in the specified path.\n"
+    "  -M                 Print make rules for generated files.\n"
+    "  --version          Print the version number of flatc and exit.\n"
+    "  --strict-json      Strict JSON: field names must be / will be quoted,\n"
+    "                     no trailing commas in tables/vectors.\n"
+    "  --allow-non-utf8   Pass non-UTF-8 input through parser and emit nonstandard\n"
+    "                     \\x escapes in JSON. (Default is to raise parse error on\n"
+    "                     non-UTF-8 input.)\n"
+    "  --natural-utf8     Output strings with UTF-8 as human-readable strings.\n"
+    "                     By default, UTF-8 characters are printed as \\uXXXX escapes.\n"
+    "  --defaults-json    Output fields whose value is the default when\n"
+    "                     writing JSON\n"
+    "  --unknown-json     Allow fields in JSON that are not defined in the\n"
+    "                     schema. These fields will be discared when generating\n"
+    "                     binaries.\n"
+    "  --no-prefix        Don\'t prefix enum values with the enum type in C++.\n"
+    "  --scoped-enums     Use C++11 style scoped and strongly typed enums.\n"
+    "                     also implies --no-prefix.\n"
+    "  --gen-includes     (deprecated), this is the default behavior.\n"
+    "                     If the original behavior is required (no include\n"
+    "                     statements) use --no-includes.\n"
+    "  --no-includes      Don\'t generate include statements for included\n"
+    "                     schemas the generated file depends on (C++).\n"
+    "  --gen-mutable      Generate accessors that can mutate buffers in-place.\n"
+    "  --gen-onefile      Generate single output file for C# and Go.\n"
+    "  --gen-name-strings Generate type name functions for C++.\n"
+    "  --gen-object-api   Generate an additional object-based API.\n"
+    "  --gen-compare      Generate operator== for object-based API types.\n"
+    "  --gen-nullable     Add Clang _Nullable for C++ pointer. or @Nullable for Java\n"
+    "  --gen-generated    Add @Generated annotation for Java\n"
+    "  --gen-all          Generate not just code for the current schema files,\n"
+    "                     but for all files it includes as well.\n"
+    "                     If the language uses a single file for output (by default\n"
+    "                     the case for C++ and JS), all code will end up in this one\n"
+    "                     file.\n"
+    "  --cpp-include      Adds an #include in generated file.\n"
+    "  --cpp-ptr-type T   Set object API pointer type (default std::unique_ptr).\n"
+    "  --cpp-str-type T   Set object API string type (default std::string).\n"
+    "                     T::c_str(), T::length() and T::empty() must be supported.\n"
+    "                     The custom type also needs to be constructible from std::string\n"
+    "                     (see the --cpp-str-flex-ctor option to change this behavior).\n"
+    "  --cpp-str-flex-ctor Don't construct custom string types by passing std::string\n"
+    "                     from Flatbuffers, but (char* + length).\n"
+    "  --object-prefix    Customise class prefix for C++ object-based API.\n"
+    "  --object-suffix    Customise class suffix for C++ object-based API.\n"
+    "                     Default value is \"T\".\n"
+    "  --no-js-exports    Removes Node.js style export lines in JS.\n"
+    "  --goog-js-export   Uses goog.exports* for closure compiler exporting in JS.\n"
+    "  --es6-js-export    Uses ECMAScript 6 export style lines in JS.\n"
+    "  --go-namespace     Generate the overrided namespace in Golang.\n"
+    "  --go-import        Generate the overrided import for flatbuffers in Golang\n"
+    "                     (default is \"github.com/google/flatbuffers/go\").\n"
+    "  --raw-binary       Allow binaries without file_indentifier to be read.\n"
+    "                     This may crash flatc given a mismatched schema.\n"
+    "  --size-prefixed    Input binaries are size prefixed buffers.\n"
+    "  --proto            Input is a .proto, translate to .fbs.\n"
+    "  --oneof-union      Translate .proto oneofs to flatbuffer unions.\n"
+    "  --grpc             Generate GRPC interfaces for the specified languages.\n"
+    "  --schema           Serialize schemas instead of JSON (use with -b).\n"
+    "  --bfbs-comments    Add doc comments to the binary schema files.\n"
+    "  --bfbs-builtins    Add builtin attributes to the binary schema files.\n"
+    "  --conform FILE     Specify a schema the following schemas should be\n"
+    "                     an evolution of. Gives errors if not.\n"
+    "  --conform-includes Include path for the schema given with --conform PATH\n"
+    "  --include-prefix   Prefix this path to any generated include statements.\n"
+    "    PATH\n"
+    "  --keep-prefix      Keep original prefix of schema include statement.\n"
+    "  --no-fb-import     Don't include flatbuffers import statement for TypeScript.\n"
+    "  --no-ts-reexport   Don't re-export imported dependencies for TypeScript.\n"
+    "  --short-names      Use short function names for JS and TypeScript.\n"
+    "  --reflect-types    Add minimal type reflection to code generation.\n"
+    "  --reflect-names    Add minimal type/name reflection.\n"
+    "  --root-type T      Select or override the default root_type\n"
+    "  --force-defaults   Emit default values in binary output from JSON\n"
+    "  --force-empty      When serializing from object API representation,\n"
+    "                     force strings and vectors to empty rather than null.\n"
+    "FILEs may be schemas (must end in .fbs), binary schemas (must end in .bfbs),\n"
+    "or JSON files (conforming to preceding schema). FILEs after the -- must be\n"
+    "binary flatbuffer format files.\n"
+    "Output files are named using the base file name of the input,\n"
+    "and written to the current directory or the path given by -o.\n"
+    "example: " << program_name << " -c -b schema1.fbs schema2.fbs data.json\n";
+  // clang-format on
+  return ss.str();
+}
+
+int FlatCompiler::Compile(int argc, const char **argv) {
+  if (params_.generators == nullptr || params_.num_generators == 0) {
+    return 0;
+  }
+
+  flatbuffers::IDLOptions opts;
+  std::string output_path;
+
+  bool any_generator = false;
+  bool print_make_rules = false;
+  bool raw_binary = false;
+  bool schema_binary = false;
+  bool grpc_enabled = false;
+  std::vector<std::string> filenames;
+  std::list<std::string> include_directories_storage;
+  std::vector<const char *> include_directories;
+  std::vector<const char *> conform_include_directories;
+  std::vector<bool> generator_enabled(params_.num_generators, false);
+  size_t binary_files_from = std::numeric_limits<size_t>::max();
+  std::string conform_to_schema;
+
+  for (int argi = 0; argi < argc; argi++) {
+    std::string arg = argv[argi];
+    if (arg[0] == '-') {
+      if (filenames.size() && arg[1] != '-')
+        Error("invalid option location: " + arg, true);
+      if (arg == "-o") {
+        if (++argi >= argc) Error("missing path following: " + arg, true);
+        output_path = flatbuffers::ConCatPathFileName(
+            flatbuffers::PosixPath(argv[argi]), "");
+      } else if (arg == "-I") {
+        if (++argi >= argc) Error("missing path following" + arg, true);
+        include_directories_storage.push_back(
+            flatbuffers::PosixPath(argv[argi]));
+        include_directories.push_back(
+            include_directories_storage.back().c_str());
+      } else if (arg == "--conform") {
+        if (++argi >= argc) Error("missing path following" + arg, true);
+        conform_to_schema = flatbuffers::PosixPath(argv[argi]);
+      } else if (arg == "--conform-includes") {
+        if (++argi >= argc) Error("missing path following" + arg, true);
+        include_directories_storage.push_back(
+            flatbuffers::PosixPath(argv[argi]));
+        conform_include_directories.push_back(
+            include_directories_storage.back().c_str());
+      } else if (arg == "--include-prefix") {
+        if (++argi >= argc) Error("missing path following" + arg, true);
+        opts.include_prefix = flatbuffers::ConCatPathFileName(
+            flatbuffers::PosixPath(argv[argi]), "");
+      } else if (arg == "--keep-prefix") {
+        opts.keep_include_path = true;
+      } else if (arg == "--strict-json") {
+        opts.strict_json = true;
+      } else if (arg == "--allow-non-utf8") {
+        opts.allow_non_utf8 = true;
+      } else if (arg == "--natural-utf8") {
+        opts.natural_utf8 = true;
+      } else if (arg == "--no-js-exports") {
+        opts.skip_js_exports = true;
+      } else if (arg == "--goog-js-export") {
+        opts.use_goog_js_export_format = true;
+        opts.use_ES6_js_export_format = false;
+      } else if (arg == "--es6-js-export") {
+        opts.use_goog_js_export_format = false;
+        opts.use_ES6_js_export_format = true;
+      } else if (arg == "--go-namespace") {
+        if (++argi >= argc) Error("missing golang namespace" + arg, true);
+        opts.go_namespace = argv[argi];
+      } else if (arg == "--go-import") {
+        if (++argi >= argc) Error("missing golang import" + arg, true);
+        opts.go_import = argv[argi];
+      } else if (arg == "--defaults-json") {
+        opts.output_default_scalars_in_json = true;
+      } else if (arg == "--unknown-json") {
+        opts.skip_unexpected_fields_in_json = true;
+      } else if (arg == "--no-prefix") {
+        opts.prefixed_enums = false;
+      } else if (arg == "--scoped-enums") {
+        opts.prefixed_enums = false;
+        opts.scoped_enums = true;
+      } else if (arg == "--no-union-value-namespacing") {
+        opts.union_value_namespacing = false;
+      } else if (arg == "--gen-mutable") {
+        opts.mutable_buffer = true;
+      } else if (arg == "--gen-name-strings") {
+        opts.generate_name_strings = true;
+      } else if (arg == "--gen-object-api") {
+        opts.generate_object_based_api = true;
+      } else if (arg == "--gen-compare") {
+        opts.gen_compare = true;
+      } else if (arg == "--cpp-include") {
+        if (++argi >= argc) Error("missing include following" + arg, true);
+        opts.cpp_includes.push_back(argv[argi]);
+      } else if (arg == "--cpp-ptr-type") {
+        if (++argi >= argc) Error("missing type following" + arg, true);
+        opts.cpp_object_api_pointer_type = argv[argi];
+      } else if (arg == "--cpp-str-type") {
+        if (++argi >= argc) Error("missing type following" + arg, true);
+        opts.cpp_object_api_string_type = argv[argi];
+      } else if (arg == "--cpp-str-flex-ctor") {
+        opts.cpp_object_api_string_flexible_constructor = true;
+      } else if (arg == "--gen-nullable") {
+        opts.gen_nullable = true;
+      } else if (arg == "--gen-generated") {
+        opts.gen_generated = true;
+      } else if (arg == "--object-prefix") {
+        if (++argi >= argc) Error("missing prefix following" + arg, true);
+        opts.object_prefix = argv[argi];
+      } else if (arg == "--object-suffix") {
+        if (++argi >= argc) Error("missing suffix following" + arg, true);
+        opts.object_suffix = argv[argi];
+      } else if (arg == "--gen-all") {
+        opts.generate_all = true;
+        opts.include_dependence_headers = false;
+      } else if (arg == "--gen-includes") {
+        // Deprecated, remove this option some time in the future.
+        printf("warning: --gen-includes is deprecated (it is now default)\n");
+      } else if (arg == "--no-includes") {
+        opts.include_dependence_headers = false;
+      } else if (arg == "--gen-onefile") {
+        opts.one_file = true;
+      } else if (arg == "--raw-binary") {
+        raw_binary = true;
+      } else if (arg == "--size-prefixed") {
+        opts.size_prefixed = true;
+      } else if (arg == "--") {  // Separator between text and binary inputs.
+        binary_files_from = filenames.size();
+      } else if (arg == "--proto") {
+        opts.proto_mode = true;
+      } else if (arg == "--oneof-union") {
+        opts.proto_oneof_union = true;
+      } else if (arg == "--schema") {
+        schema_binary = true;
+      } else if (arg == "-M") {
+        print_make_rules = true;
+      } else if (arg == "--version") {
+        printf("flatc version %s\n", FLATC_VERSION());
+        exit(0);
+      } else if (arg == "--grpc") {
+        grpc_enabled = true;
+      } else if (arg == "--bfbs-comments") {
+        opts.binary_schema_comments = true;
+      } else if (arg == "--bfbs-builtins") {
+        opts.binary_schema_builtins = true;
+      } else if (arg == "--no-fb-import") {
+        opts.skip_flatbuffers_import = true;
+      } else if (arg == "--no-ts-reexport") {
+        opts.reexport_ts_modules = false;
+      } else if (arg == "--short-names") {
+        opts.js_ts_short_names = true;
+      } else if (arg == "--reflect-types") {
+        opts.mini_reflect = IDLOptions::kTypes;
+      } else if (arg == "--reflect-names") {
+        opts.mini_reflect = IDLOptions::kTypesAndNames;
+      } else if (arg == "--root-type") {
+        if (++argi >= argc) Error("missing type following" + arg, true);
+        opts.root_type = argv[argi];
+      } else if (arg == "--force-defaults") {
+        opts.force_defaults = true;
+      } else if (arg == "--force-empty") {
+        opts.set_empty_to_null = false;
+      } else {
+        for (size_t i = 0; i < params_.num_generators; ++i) {
+          if (arg == params_.generators[i].generator_opt_long ||
+              (params_.generators[i].generator_opt_short &&
+               arg == params_.generators[i].generator_opt_short)) {
+            generator_enabled[i] = true;
+            any_generator = true;
+            opts.lang_to_generate |= params_.generators[i].lang;
+            goto found;
+          }
+        }
+        Error("unknown commandline argument: " + arg, true);
+      found:;
+      }
+    } else {
+      filenames.push_back(flatbuffers::PosixPath(argv[argi]));
+    }
+  }
+
+  if (!filenames.size()) Error("missing input files", false, true);
+
+  if (opts.proto_mode) {
+    if (any_generator)
+      Error("cannot generate code directly from .proto files", true);
+  } else if (!any_generator && conform_to_schema.empty()) {
+    Error("no options: specify at least one generator.", true);
+  }
+
+  flatbuffers::Parser conform_parser;
+  if (!conform_to_schema.empty()) {
+    std::string contents;
+    if (!flatbuffers::LoadFile(conform_to_schema.c_str(), true, &contents))
+      Error("unable to load schema: " + conform_to_schema);
+
+    if (flatbuffers::GetExtension(conform_to_schema) ==
+        reflection::SchemaExtension()) {
+      LoadBinarySchema(conform_parser, conform_to_schema, contents);
+    } else {
+      ParseFile(conform_parser, conform_to_schema, contents,
+                conform_include_directories);
+    }
+  }
+
+  std::unique_ptr<flatbuffers::Parser> parser(new flatbuffers::Parser(opts));
+
+  for (auto file_it = filenames.begin(); file_it != filenames.end();
+       ++file_it) {
+    auto &filename = *file_it;
+    std::string contents;
+    if (!flatbuffers::LoadFile(filename.c_str(), true, &contents))
+      Error("unable to load file: " + filename);
+
+    bool is_binary =
+        static_cast<size_t>(file_it - filenames.begin()) >= binary_files_from;
+    auto ext = flatbuffers::GetExtension(filename);
+    auto is_schema = ext == "fbs" || ext == "proto";
+    auto is_binary_schema = ext == reflection::SchemaExtension();
+    if (is_binary) {
+      parser->builder_.Clear();
+      parser->builder_.PushFlatBuffer(
+          reinterpret_cast<const uint8_t *>(contents.c_str()),
+          contents.length());
+      if (!raw_binary) {
+        // Generally reading binaries that do not correspond to the schema
+        // will crash, and sadly there's no way around that when the binary
+        // does not contain a file identifier.
+        // We'd expect that typically any binary used as a file would have
+        // such an identifier, so by default we require them to match.
+        if (!parser->file_identifier_.length()) {
+          Error("current schema has no file_identifier: cannot test if \"" +
+                filename +
+                "\" matches the schema, use --raw-binary to read this file"
+                " anyway.");
+        } else if (!flatbuffers::BufferHasIdentifier(
+                       contents.c_str(), parser->file_identifier_.c_str(), opts.size_prefixed)) {
+          Error("binary \"" + filename +
+                "\" does not have expected file_identifier \"" +
+                parser->file_identifier_ +
+                "\", use --raw-binary to read this file anyway.");
+        }
+      }
+    } else {
+      // Check if file contains 0 bytes.
+      if (!is_binary_schema && contents.length() != strlen(contents.c_str())) {
+        Error("input file appears to be binary: " + filename, true);
+      }
+      if (is_schema) {
+        // If we're processing multiple schemas, make sure to start each
+        // one from scratch. If it depends on previous schemas it must do
+        // so explicitly using an include.
+        parser.reset(new flatbuffers::Parser(opts));
+      }
+      if (is_binary_schema) {
+        LoadBinarySchema(*parser.get(), filename, contents);
+      } else {
+        ParseFile(*parser.get(), filename, contents, include_directories);
+        if (!is_schema && !parser->builder_.GetSize()) {
+          // If a file doesn't end in .fbs, it must be json/binary. Ensure we
+          // didn't just parse a schema with a different extension.
+          Error("input file is neither json nor a .fbs (schema) file: " +
+                    filename,
+                true);
+        }
+      }
+      if ((is_schema || is_binary_schema) && !conform_to_schema.empty()) {
+        auto err = parser->ConformTo(conform_parser);
+        if (!err.empty()) Error("schemas don\'t conform: " + err);
+      }
+      if (schema_binary) {
+        parser->Serialize();
+        parser->file_extension_ = reflection::SchemaExtension();
+      }
+    }
+
+    std::string filebase =
+        flatbuffers::StripPath(flatbuffers::StripExtension(filename));
+
+    for (size_t i = 0; i < params_.num_generators; ++i) {
+      parser->opts.lang = params_.generators[i].lang;
+      if (generator_enabled[i]) {
+        if (!print_make_rules) {
+          flatbuffers::EnsureDirExists(output_path);
+          if ((!params_.generators[i].schema_only ||
+               (is_schema || is_binary_schema)) &&
+              !params_.generators[i].generate(*parser.get(), output_path,
+                                              filebase)) {
+            Error(std::string("Unable to generate ") +
+                  params_.generators[i].lang_name + " for " + filebase);
+          }
+        } else {
+          std::string make_rule = params_.generators[i].make_rule(
+              *parser.get(), output_path, filename);
+          if (!make_rule.empty())
+            printf("%s\n",
+                   flatbuffers::WordWrap(make_rule, 80, " ", " \\").c_str());
+        }
+        if (grpc_enabled) {
+          if (params_.generators[i].generateGRPC != nullptr) {
+            if (!params_.generators[i].generateGRPC(*parser.get(), output_path,
+                                                    filebase)) {
+              Error(std::string("Unable to generate GRPC interface for") +
+                    params_.generators[i].lang_name);
+            }
+          } else {
+            Warn(std::string("GRPC interface generator not implemented for ") +
+                 params_.generators[i].lang_name);
+          }
+        }
+      }
+    }
+
+    if (!opts.root_type.empty()) {
+      if (!parser->SetRootType(opts.root_type.c_str()))
+        Error("unknown root type: " + opts.root_type);
+      else if (parser->root_struct_def_->fixed)
+        Error("root type must be a table");
+    }
+
+    if (opts.proto_mode) GenerateFBS(*parser.get(), output_path, filebase);
+
+    // We do not want to generate code for the definitions in this file
+    // in any files coming up next.
+    parser->MarkGenerated();
+  }
+  return 0;
+}
+
+}  // namespace flatbuffers
diff --git a/src/flatc_main.cpp b/src/flatc_main.cpp
new file mode 100644
index 0000000..72bb4a2
--- /dev/null
+++ b/src/flatc_main.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2017 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "flatbuffers/flatc.h"
+#include "flatbuffers/util.h"
+
+static const char *g_program_name = nullptr;
+
+static void Warn(const flatbuffers::FlatCompiler *flatc,
+                 const std::string &warn, bool show_exe_name) {
+  (void)flatc;
+  if (show_exe_name) { printf("%s: ", g_program_name); }
+  printf("warning: %s\n", warn.c_str());
+}
+
+static void Error(const flatbuffers::FlatCompiler *flatc,
+                  const std::string &err, bool usage, bool show_exe_name) {
+  if (show_exe_name) { printf("%s: ", g_program_name); }
+  printf("error: %s\n", err.c_str());
+  if (usage) { printf("%s", flatc->GetUsageString(g_program_name).c_str()); }
+  exit(1);
+}
+
+int main(int argc, const char *argv[]) {
+  // Prevent Appveyor-CI hangs.
+  flatbuffers::SetupDefaultCRTReportMode();
+
+  g_program_name = argv[0];
+
+  const flatbuffers::FlatCompiler::Generator generators[] = {
+    { flatbuffers::GenerateBinary, "-b", "--binary", "binary", false, nullptr,
+      flatbuffers::IDLOptions::kBinary,
+      "Generate wire format binaries for any data definitions",
+      flatbuffers::BinaryMakeRule },
+    { flatbuffers::GenerateTextFile, "-t", "--json", "text", false, nullptr,
+      flatbuffers::IDLOptions::kJson,
+      "Generate text output for any data definitions",
+      flatbuffers::TextMakeRule },
+    { flatbuffers::GenerateCPP, "-c", "--cpp", "C++", true,
+      flatbuffers::GenerateCppGRPC, flatbuffers::IDLOptions::kCpp,
+      "Generate C++ headers for tables/structs", flatbuffers::CPPMakeRule },
+    { flatbuffers::GenerateGo, "-g", "--go", "Go", true,
+      flatbuffers::GenerateGoGRPC, flatbuffers::IDLOptions::kGo,
+      "Generate Go files for tables/structs", flatbuffers::GeneralMakeRule },
+    { flatbuffers::GenerateGeneral, "-j", "--java", "Java", true,
+      flatbuffers::GenerateJavaGRPC, flatbuffers::IDLOptions::kJava,
+      "Generate Java classes for tables/structs",
+      flatbuffers::GeneralMakeRule },
+    { flatbuffers::GenerateJSTS, "-s", "--js", "JavaScript", true, nullptr,
+      flatbuffers::IDLOptions::kJs,
+      "Generate JavaScript code for tables/structs", flatbuffers::JSTSMakeRule },
+    { flatbuffers::GenerateDart, "-d", "--dart", "Dart", true, nullptr,
+      flatbuffers::IDLOptions::kDart,
+      "Generate Dart classes for tables/structs", flatbuffers::DartMakeRule },
+    { flatbuffers::GenerateJSTS, "-T", "--ts", "TypeScript", true, nullptr,
+      flatbuffers::IDLOptions::kTs,
+      "Generate TypeScript code for tables/structs", flatbuffers::JSTSMakeRule },
+    { flatbuffers::GenerateGeneral, "-n", "--csharp", "C#", true, nullptr,
+      flatbuffers::IDLOptions::kCSharp,
+      "Generate C# classes for tables/structs", flatbuffers::GeneralMakeRule },
+    { flatbuffers::GeneratePython, "-p", "--python", "Python", true, nullptr,
+      flatbuffers::IDLOptions::kPython,
+      "Generate Python files for tables/structs",
+      flatbuffers::GeneralMakeRule },
+    { flatbuffers::GenerateLobster, nullptr, "--lobster", "Lobster", true, nullptr,
+      flatbuffers::IDLOptions::kLobster,
+      "Generate Lobster files for tables/structs",
+      flatbuffers::GeneralMakeRule },
+    { flatbuffers::GenerateLua, "-l", "--lua", "Lua", true, nullptr,
+      flatbuffers::IDLOptions::kLua,
+      "Generate Lua files for tables/structs",
+      flatbuffers::GeneralMakeRule },
+    { flatbuffers::GenerateRust, "-r", "--rust", "Rust", true, nullptr,
+      flatbuffers::IDLOptions::kRust,
+      "Generate Rust files for tables/structs",
+      flatbuffers::RustMakeRule },
+    { flatbuffers::GeneratePhp, nullptr, "--php", "PHP", true, nullptr,
+      flatbuffers::IDLOptions::kPhp, "Generate PHP files for tables/structs",
+      flatbuffers::GeneralMakeRule },
+    { flatbuffers::GenerateKotlin, nullptr, "--kotlin", "Kotlin", true, nullptr,
+      flatbuffers::IDLOptions::kKotlin, "Generate Kotlin classes for tables/structs",
+      flatbuffers::GeneralMakeRule },
+    { flatbuffers::GenerateJsonSchema, nullptr, "--jsonschema", "JsonSchema",
+      true, nullptr, flatbuffers::IDLOptions::kJsonSchema,
+      "Generate Json schema", flatbuffers::GeneralMakeRule },
+  };
+
+  flatbuffers::FlatCompiler::InitParams params;
+  params.generators = generators;
+  params.num_generators = sizeof(generators) / sizeof(generators[0]);
+  params.warn_fn = Warn;
+  params.error_fn = Error;
+
+  flatbuffers::FlatCompiler flatc(params);
+  return flatc.Compile(argc - 1, argv + 1);
+}
diff --git a/src/flathash.cpp b/src/flathash.cpp
new file mode 100644
index 0000000..bc3d2df
--- /dev/null
+++ b/src/flathash.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2015 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include "flatbuffers/hash.h"
+
+enum OutputFormat { kDecimal, kHexadecimal, kHexadecimal0x };
+
+int main(int argc, char *argv[]) {
+  const char *name = argv[0];
+  if (argc <= 1) {
+    printf("%s HASH [OPTION]... [--] STRING...\n", name);
+    printf("Available hashing algorithms:\n");
+    printf("  16 bit:\n");
+    size_t size = sizeof(flatbuffers::kHashFunctions16) /
+                  sizeof(flatbuffers::kHashFunctions16[0]);
+    for (size_t i = 0; i < size; ++i) {
+      printf("    * %s\n", flatbuffers::kHashFunctions16[i].name);
+    }
+    printf("  32 bit:\n");
+    size = sizeof(flatbuffers::kHashFunctions32) /
+                  sizeof(flatbuffers::kHashFunctions32[0]);
+    for (size_t i = 0; i < size; ++i) {
+      printf("    * %s\n", flatbuffers::kHashFunctions32[i].name);
+    }
+    printf("  64 bit:\n");
+    size = sizeof(flatbuffers::kHashFunctions64) /
+           sizeof(flatbuffers::kHashFunctions64[0]);
+    for (size_t i = 0; i < size; ++i) {
+      printf("    * %s\n", flatbuffers::kHashFunctions64[i].name);
+    }
+    printf(
+        "  -d         Output hash in decimal.\n"
+        "  -x         Output hash in hexadecimal.\n"
+        "  -0x        Output hash in hexadecimal and prefix with 0x.\n"
+        "  -c         Append the string to the output in a c-style comment.\n");
+    return 1;
+  }
+
+  const char *hash_algorithm = argv[1];
+
+  flatbuffers::NamedHashFunction<uint16_t>::HashFunction hash_function16 =
+      flatbuffers::FindHashFunction16(hash_algorithm);
+  flatbuffers::NamedHashFunction<uint32_t>::HashFunction hash_function32 =
+      flatbuffers::FindHashFunction32(hash_algorithm);
+  flatbuffers::NamedHashFunction<uint64_t>::HashFunction hash_function64 =
+      flatbuffers::FindHashFunction64(hash_algorithm);
+
+  if (!hash_function16 && !hash_function32 && !hash_function64) {
+    printf("\"%s\" is not a known hash algorithm.\n", hash_algorithm);
+    return 1;
+  }
+
+  OutputFormat output_format = kHexadecimal;
+  bool annotate = false;
+  bool escape_dash = false;
+  for (int i = 2; i < argc; i++) {
+    const char *arg = argv[i];
+    if (!escape_dash && arg[0] == '-') {
+      std::string opt = arg;
+      if (opt == "-d")
+        output_format = kDecimal;
+      else if (opt == "-x")
+        output_format = kHexadecimal;
+      else if (opt == "-0x")
+        output_format = kHexadecimal0x;
+      else if (opt == "-c")
+        annotate = true;
+      else if (opt == "--")
+        escape_dash = true;
+      else
+        printf("Unrecognized argument: \"%s\"\n", arg);
+    } else {
+      std::stringstream ss;
+      if (output_format == kDecimal) {
+        ss << std::dec;
+      } else if (output_format == kHexadecimal) {
+        ss << std::hex;
+      } else if (output_format == kHexadecimal0x) {
+        ss << std::hex;
+        ss << "0x";
+      }
+      if (hash_function16)
+        ss << hash_function16(arg);
+      else if (hash_function32)
+        ss << hash_function32(arg);
+      else if (hash_function64)
+        ss << hash_function64(arg);
+
+      if (annotate) ss << " /* \"" << arg << "\" */";
+
+      ss << "\n";
+
+      std::cout << ss.str();
+    }
+  }
+  return 0;
+}
diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp
new file mode 100644
index 0000000..b667ea4
--- /dev/null
+++ b/src/idl_gen_cpp.cpp
@@ -0,0 +1,2972 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// independent from idl_parser, since this code is not needed for most clients
+
+#include "flatbuffers/code_generators.h"
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+#include <unordered_set>
+
+namespace flatbuffers {
+
+// Pedantic warning free version of toupper().
+inline char ToUpper(char c) { return static_cast<char>(::toupper(c)); }
+
+// Make numerical literal with type-suffix.
+// This function is only needed for C++! Other languages do not need it.
+static inline std::string NumToStringCpp(std::string val, BaseType type) {
+  // Avoid issues with -2147483648, -9223372036854775808.
+  switch (type) {
+    case BASE_TYPE_INT:
+      return (val != "-2147483648") ? val : ("(-2147483647 - 1)");
+    case BASE_TYPE_ULONG: return (val == "0") ? val : (val + "ULL");
+    case BASE_TYPE_LONG:
+      if (val == "-9223372036854775808")
+        return "(-9223372036854775807LL - 1LL)";
+      else
+        return (val == "0") ? val : (val + "LL");
+    default: return val;
+  }
+}
+
+static std::string GeneratedFileName(const std::string &path,
+                                     const std::string &file_name) {
+  return path + file_name + "_generated.h";
+}
+
+namespace cpp {
+class CppGenerator : public BaseGenerator {
+ public:
+  CppGenerator(const Parser &parser, const std::string &path,
+               const std::string &file_name)
+      : BaseGenerator(parser, path, file_name, "", "::"),
+        cur_name_space_(nullptr),
+        float_const_gen_("std::numeric_limits<double>::",
+                         "std::numeric_limits<float>::", "quiet_NaN()",
+                         "infinity()") {
+    static const char *const keywords[] = {
+      "alignas",
+      "alignof",
+      "and",
+      "and_eq",
+      "asm",
+      "atomic_cancel",
+      "atomic_commit",
+      "atomic_noexcept",
+      "auto",
+      "bitand",
+      "bitor",
+      "bool",
+      "break",
+      "case",
+      "catch",
+      "char",
+      "char16_t",
+      "char32_t",
+      "class",
+      "compl",
+      "concept",
+      "const",
+      "constexpr",
+      "const_cast",
+      "continue",
+      "co_await",
+      "co_return",
+      "co_yield",
+      "decltype",
+      "default",
+      "delete",
+      "do",
+      "double",
+      "dynamic_cast",
+      "else",
+      "enum",
+      "explicit",
+      "export",
+      "extern",
+      "false",
+      "float",
+      "for",
+      "friend",
+      "goto",
+      "if",
+      "import",
+      "inline",
+      "int",
+      "long",
+      "module",
+      "mutable",
+      "namespace",
+      "new",
+      "noexcept",
+      "not",
+      "not_eq",
+      "nullptr",
+      "operator",
+      "or",
+      "or_eq",
+      "private",
+      "protected",
+      "public",
+      "register",
+      "reinterpret_cast",
+      "requires",
+      "return",
+      "short",
+      "signed",
+      "sizeof",
+      "static",
+      "static_assert",
+      "static_cast",
+      "struct",
+      "switch",
+      "synchronized",
+      "template",
+      "this",
+      "thread_local",
+      "throw",
+      "true",
+      "try",
+      "typedef",
+      "typeid",
+      "typename",
+      "union",
+      "unsigned",
+      "using",
+      "virtual",
+      "void",
+      "volatile",
+      "wchar_t",
+      "while",
+      "xor",
+      "xor_eq",
+      nullptr,
+    };
+    for (auto kw = keywords; *kw; kw++) keywords_.insert(*kw);
+  }
+
+  std::string GenIncludeGuard() const {
+    // Generate include guard.
+    std::string guard = file_name_;
+    // Remove any non-alpha-numeric characters that may appear in a filename.
+    struct IsAlnum {
+      bool operator()(char c) const { return !is_alnum(c); }
+    };
+    guard.erase(std::remove_if(guard.begin(), guard.end(), IsAlnum()),
+                guard.end());
+    guard = "FLATBUFFERS_GENERATED_" + guard;
+    guard += "_";
+    // For further uniqueness, also add the namespace.
+    auto name_space = parser_.current_namespace_;
+    for (auto it = name_space->components.begin();
+         it != name_space->components.end(); ++it) {
+      guard += *it + "_";
+    }
+    guard += "H_";
+    std::transform(guard.begin(), guard.end(), guard.begin(), ToUpper);
+    return guard;
+  }
+
+  void GenIncludeDependencies() {
+    int num_includes = 0;
+    for (auto it = parser_.native_included_files_.begin();
+         it != parser_.native_included_files_.end(); ++it) {
+      code_ += "#include \"" + *it + "\"";
+      num_includes++;
+    }
+    for (auto it = parser_.included_files_.begin();
+         it != parser_.included_files_.end(); ++it) {
+      if (it->second.empty()) continue;
+      auto noext = flatbuffers::StripExtension(it->second);
+      auto basename = flatbuffers::StripPath(noext);
+
+      code_ += "#include \"" + parser_.opts.include_prefix +
+               (parser_.opts.keep_include_path ? noext : basename) +
+               "_generated.h\"";
+      num_includes++;
+    }
+    if (num_includes) code_ += "";
+  }
+
+  void GenExtraIncludes() {
+    for(std::size_t i = 0; i < parser_.opts.cpp_includes.size(); ++i) {
+      code_ += "#include \"" + parser_.opts.cpp_includes[i] + "\"";
+    }
+    if (!parser_.opts.cpp_includes.empty()) {
+      code_ += "";
+    }
+  }
+
+  std::string EscapeKeyword(const std::string &name) const {
+    return keywords_.find(name) == keywords_.end() ? name : name + "_";
+  }
+
+  std::string Name(const Definition &def) const {
+    return EscapeKeyword(def.name);
+  }
+
+  std::string Name(const EnumVal &ev) const { return EscapeKeyword(ev.name); }
+
+  // Iterate through all definitions we haven't generate code for (enums,
+  // structs, and tables) and output them to a single file.
+  bool generate() {
+    code_.Clear();
+    code_ += "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n";
+
+    const auto include_guard = GenIncludeGuard();
+    code_ += "#ifndef " + include_guard;
+    code_ += "#define " + include_guard;
+    code_ += "";
+
+    if (parser_.opts.gen_nullable) {
+      code_ += "#pragma clang system_header\n\n";
+    }
+
+    code_ += "#include \"flatbuffers/flatbuffers.h\"";
+    if (parser_.uses_flexbuffers_) {
+      code_ += "#include \"flatbuffers/flexbuffers.h\"";
+    }
+    code_ += "";
+
+    if (parser_.opts.include_dependence_headers) { GenIncludeDependencies(); }
+    GenExtraIncludes();
+
+    FLATBUFFERS_ASSERT(!cur_name_space_);
+
+    // Generate forward declarations for all structs/tables, since they may
+    // have circular references.
+    for (auto it = parser_.structs_.vec.begin();
+         it != parser_.structs_.vec.end(); ++it) {
+      const auto &struct_def = **it;
+      if (!struct_def.generated) {
+        SetNameSpace(struct_def.defined_namespace);
+        code_ += "struct " + Name(struct_def) + ";";
+        if (parser_.opts.generate_object_based_api) {
+          auto nativeName =
+              NativeName(Name(struct_def), &struct_def, parser_.opts);
+          if (!struct_def.fixed) { code_ += "struct " + nativeName + ";"; }
+        }
+        code_ += "";
+      }
+    }
+
+    // Generate forward declarations for all equal operators
+    if (parser_.opts.generate_object_based_api && parser_.opts.gen_compare) {
+      for (auto it = parser_.structs_.vec.begin();
+           it != parser_.structs_.vec.end(); ++it) {
+        const auto &struct_def = **it;
+        if (!struct_def.generated) {
+          SetNameSpace(struct_def.defined_namespace);
+          auto nativeName =
+              NativeName(Name(struct_def), &struct_def, parser_.opts);
+          code_ += "bool operator==(const " + nativeName + " &lhs, const " +
+                   nativeName + " &rhs);";
+          code_ += "bool operator!=(const " + nativeName + " &lhs, const " +
+              nativeName + " &rhs);";
+        }
+      }
+      code_ += "";
+    }
+
+    // Generate preablmle code for mini reflection.
+    if (parser_.opts.mini_reflect != IDLOptions::kNone) {
+      // To break cyclic dependencies, first pre-declare all tables/structs.
+      for (auto it = parser_.structs_.vec.begin();
+           it != parser_.structs_.vec.end(); ++it) {
+        const auto &struct_def = **it;
+        if (!struct_def.generated) {
+          SetNameSpace(struct_def.defined_namespace);
+          GenMiniReflectPre(&struct_def);
+        }
+      }
+    }
+
+    // Generate code for all the enum declarations.
+    for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
+         ++it) {
+      const auto &enum_def = **it;
+      if (!enum_def.generated) {
+        SetNameSpace(enum_def.defined_namespace);
+        GenEnum(enum_def);
+      }
+    }
+
+    // Generate code for all structs, then all tables.
+    for (auto it = parser_.structs_.vec.begin();
+         it != parser_.structs_.vec.end(); ++it) {
+      const auto &struct_def = **it;
+      if (struct_def.fixed && !struct_def.generated) {
+        SetNameSpace(struct_def.defined_namespace);
+        GenStruct(struct_def);
+      }
+    }
+    for (auto it = parser_.structs_.vec.begin();
+         it != parser_.structs_.vec.end(); ++it) {
+      const auto &struct_def = **it;
+      if (!struct_def.fixed && !struct_def.generated) {
+        SetNameSpace(struct_def.defined_namespace);
+        GenTable(struct_def);
+      }
+    }
+    for (auto it = parser_.structs_.vec.begin();
+         it != parser_.structs_.vec.end(); ++it) {
+      const auto &struct_def = **it;
+      if (!struct_def.fixed && !struct_def.generated) {
+        SetNameSpace(struct_def.defined_namespace);
+        GenTablePost(struct_def);
+      }
+    }
+
+    // Generate code for union verifiers.
+    for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
+         ++it) {
+      const auto &enum_def = **it;
+      if (enum_def.is_union && !enum_def.generated) {
+        SetNameSpace(enum_def.defined_namespace);
+        GenUnionPost(enum_def);
+      }
+    }
+
+    // Generate code for mini reflection.
+    if (parser_.opts.mini_reflect != IDLOptions::kNone) {
+      // Then the unions/enums that may refer to them.
+      for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
+           ++it) {
+        const auto &enum_def = **it;
+        if (!enum_def.generated) {
+          SetNameSpace(enum_def.defined_namespace);
+          GenMiniReflect(nullptr, &enum_def);
+        }
+      }
+      // Then the full tables/structs.
+      for (auto it = parser_.structs_.vec.begin();
+           it != parser_.structs_.vec.end(); ++it) {
+        const auto &struct_def = **it;
+        if (!struct_def.generated) {
+          SetNameSpace(struct_def.defined_namespace);
+          GenMiniReflect(&struct_def, nullptr);
+        }
+      }
+    }
+
+    // Generate convenient global helper functions:
+    if (parser_.root_struct_def_) {
+      auto &struct_def = *parser_.root_struct_def_;
+      SetNameSpace(struct_def.defined_namespace);
+      auto name = Name(struct_def);
+      auto qualified_name = cur_name_space_->GetFullyQualifiedName(name);
+      auto cpp_name = TranslateNameSpace(qualified_name);
+
+      code_.SetValue("STRUCT_NAME", name);
+      code_.SetValue("CPP_NAME", cpp_name);
+      code_.SetValue("NULLABLE_EXT", NullableExtension());
+
+      // The root datatype accessor:
+      code_ += "inline \\";
+      code_ +=
+          "const {{CPP_NAME}} *{{NULLABLE_EXT}}Get{{STRUCT_NAME}}(const void "
+          "*buf) {";
+      code_ += "  return flatbuffers::GetRoot<{{CPP_NAME}}>(buf);";
+      code_ += "}";
+      code_ += "";
+
+      code_ += "inline \\";
+      code_ +=
+          "const {{CPP_NAME}} "
+          "*{{NULLABLE_EXT}}GetSizePrefixed{{STRUCT_NAME}}(const void "
+          "*buf) {";
+      code_ += "  return flatbuffers::GetSizePrefixedRoot<{{CPP_NAME}}>(buf);";
+      code_ += "}";
+      code_ += "";
+
+      if (parser_.opts.mutable_buffer) {
+        code_ += "inline \\";
+        code_ += "{{STRUCT_NAME}} *GetMutable{{STRUCT_NAME}}(void *buf) {";
+        code_ += "  return flatbuffers::GetMutableRoot<{{STRUCT_NAME}}>(buf);";
+        code_ += "}";
+        code_ += "";
+      }
+
+      if (parser_.file_identifier_.length()) {
+        // Return the identifier
+        code_ += "inline const char *{{STRUCT_NAME}}Identifier() {";
+        code_ += "  return \"" + parser_.file_identifier_ + "\";";
+        code_ += "}";
+        code_ += "";
+
+        // Check if a buffer has the identifier.
+        code_ += "inline \\";
+        code_ += "bool {{STRUCT_NAME}}BufferHasIdentifier(const void *buf) {";
+        code_ += "  return flatbuffers::BufferHasIdentifier(";
+        code_ += "      buf, {{STRUCT_NAME}}Identifier());";
+        code_ += "}";
+        code_ += "";
+      }
+
+      // The root verifier.
+      if (parser_.file_identifier_.length()) {
+        code_.SetValue("ID", name + "Identifier()");
+      } else {
+        code_.SetValue("ID", "nullptr");
+      }
+
+      code_ += "inline bool Verify{{STRUCT_NAME}}Buffer(";
+      code_ += "    flatbuffers::Verifier &verifier) {";
+      code_ += "  return verifier.VerifyBuffer<{{CPP_NAME}}>({{ID}});";
+      code_ += "}";
+      code_ += "";
+
+      code_ += "inline bool VerifySizePrefixed{{STRUCT_NAME}}Buffer(";
+      code_ += "    flatbuffers::Verifier &verifier) {";
+      code_ +=
+          "  return verifier.VerifySizePrefixedBuffer<{{CPP_NAME}}>({{ID}});";
+      code_ += "}";
+      code_ += "";
+
+      if (parser_.file_extension_.length()) {
+        // Return the extension
+        code_ += "inline const char *{{STRUCT_NAME}}Extension() {";
+        code_ += "  return \"" + parser_.file_extension_ + "\";";
+        code_ += "}";
+        code_ += "";
+      }
+
+      // Finish a buffer with a given root object:
+      code_ += "inline void Finish{{STRUCT_NAME}}Buffer(";
+      code_ += "    flatbuffers::FlatBufferBuilder &fbb,";
+      code_ += "    flatbuffers::Offset<{{CPP_NAME}}> root) {";
+      if (parser_.file_identifier_.length())
+        code_ += "  fbb.Finish(root, {{STRUCT_NAME}}Identifier());";
+      else
+        code_ += "  fbb.Finish(root);";
+      code_ += "}";
+      code_ += "";
+
+      code_ += "inline void FinishSizePrefixed{{STRUCT_NAME}}Buffer(";
+      code_ += "    flatbuffers::FlatBufferBuilder &fbb,";
+      code_ += "    flatbuffers::Offset<{{CPP_NAME}}> root) {";
+      if (parser_.file_identifier_.length())
+        code_ += "  fbb.FinishSizePrefixed(root, {{STRUCT_NAME}}Identifier());";
+      else
+        code_ += "  fbb.FinishSizePrefixed(root);";
+      code_ += "}";
+      code_ += "";
+
+      if (parser_.opts.generate_object_based_api) {
+        // A convenient root unpack function.
+        auto native_name =
+            NativeName(WrapInNameSpace(struct_def), &struct_def, parser_.opts);
+        code_.SetValue("UNPACK_RETURN",
+                       GenTypeNativePtr(native_name, nullptr, false));
+        code_.SetValue("UNPACK_TYPE",
+                       GenTypeNativePtr(native_name, nullptr, true));
+
+        code_ += "inline {{UNPACK_RETURN}} UnPack{{STRUCT_NAME}}(";
+        code_ += "    const void *buf,";
+        code_ += "    const flatbuffers::resolver_function_t *res = nullptr) {";
+        code_ += "  return {{UNPACK_TYPE}}\\";
+        code_ += "(Get{{STRUCT_NAME}}(buf)->UnPack(res));";
+        code_ += "}";
+        code_ += "";
+
+        code_ += "inline {{UNPACK_RETURN}} UnPackSizePrefixed{{STRUCT_NAME}}(";
+        code_ += "    const void *buf,";
+        code_ += "    const flatbuffers::resolver_function_t *res = nullptr) {";
+        code_ += "  return {{UNPACK_TYPE}}\\";
+        code_ += "(GetSizePrefixed{{STRUCT_NAME}}(buf)->UnPack(res));";
+        code_ += "}";
+        code_ += "";
+      }
+    }
+
+    if (cur_name_space_) SetNameSpace(nullptr);
+
+    // Close the include guard.
+    code_ += "#endif  // " + include_guard;
+
+    const auto file_path = GeneratedFileName(path_, file_name_);
+    const auto final_code = code_.ToString();
+    return SaveFile(file_path.c_str(), final_code, false);
+  }
+
+ private:
+  CodeWriter code_;
+
+  std::unordered_set<std::string> keywords_;
+
+  // This tracks the current namespace so we can insert namespace declarations.
+  const Namespace *cur_name_space_;
+
+  const Namespace *CurrentNameSpace() const { return cur_name_space_; }
+
+  // Translates a qualified name in flatbuffer text format to the same name in
+  // the equivalent C++ namespace.
+  static std::string TranslateNameSpace(const std::string &qualified_name) {
+    std::string cpp_qualified_name = qualified_name;
+    size_t start_pos = 0;
+    while ((start_pos = cpp_qualified_name.find('.', start_pos)) !=
+           std::string::npos) {
+      cpp_qualified_name.replace(start_pos, 1, "::");
+    }
+    return cpp_qualified_name;
+  }
+
+  void GenComment(const std::vector<std::string> &dc, const char *prefix = "") {
+    std::string text;
+    ::flatbuffers::GenComment(dc, &text, nullptr, prefix);
+    code_ += text + "\\";
+  }
+
+  // Return a C++ type from the table in idl.h
+  std::string GenTypeBasic(const Type &type, bool user_facing_type) const {
+    // clang-format off
+    static const char *const ctypename[] = {
+    #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
+                           RTYPE, KTYPE) \
+            #CTYPE,
+        FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+    #undef FLATBUFFERS_TD
+    };
+    // clang-format on
+    if (user_facing_type) {
+      if (type.enum_def) return WrapInNameSpace(*type.enum_def);
+      if (type.base_type == BASE_TYPE_BOOL) return "bool";
+    }
+    return ctypename[type.base_type];
+  }
+
+  // Return a C++ pointer type, specialized to the actual struct/table types,
+  // and vector element types.
+  std::string GenTypePointer(const Type &type) const {
+    switch (type.base_type) {
+      case BASE_TYPE_STRING: {
+        return "flatbuffers::String";
+      }
+      case BASE_TYPE_VECTOR: {
+        const auto type_name = GenTypeWire(type.VectorType(), "", false);
+        return "flatbuffers::Vector<" + type_name + ">";
+      }
+      case BASE_TYPE_STRUCT: {
+        return WrapInNameSpace(*type.struct_def);
+      }
+      case BASE_TYPE_UNION:
+      // fall through
+      default: { return "void"; }
+    }
+  }
+
+  // Return a C++ type for any type (scalar/pointer) specifically for
+  // building a flatbuffer.
+  std::string GenTypeWire(const Type &type, const char *postfix,
+                          bool user_facing_type) const {
+    if (IsScalar(type.base_type)) {
+      return GenTypeBasic(type, user_facing_type) + postfix;
+    } else if (IsStruct(type)) {
+      return "const " + GenTypePointer(type) + " *";
+    } else {
+      return "flatbuffers::Offset<" + GenTypePointer(type) + ">" + postfix;
+    }
+  }
+
+  // Return a C++ type for any type (scalar/pointer) that reflects its
+  // serialized size.
+  std::string GenTypeSize(const Type &type) const {
+    if (IsScalar(type.base_type)) {
+      return GenTypeBasic(type, false);
+    } else if (IsStruct(type)) {
+      return GenTypePointer(type);
+    } else {
+      return "flatbuffers::uoffset_t";
+    }
+  }
+
+  std::string NullableExtension() {
+    return parser_.opts.gen_nullable ? " _Nullable " : "";
+  }
+
+  static std::string NativeName(const std::string &name, const StructDef *sd,
+                                const IDLOptions &opts) {
+    return sd && !sd->fixed ? opts.object_prefix + name + opts.object_suffix
+                            : name;
+  }
+
+  const std::string &PtrType(const FieldDef *field) {
+    auto attr = field ? field->attributes.Lookup("cpp_ptr_type") : nullptr;
+    return attr ? attr->constant : parser_.opts.cpp_object_api_pointer_type;
+  }
+
+  const std::string NativeString(const FieldDef *field) {
+    auto attr = field ? field->attributes.Lookup("cpp_str_type") : nullptr;
+    auto &ret = attr ? attr->constant : parser_.opts.cpp_object_api_string_type;
+    if (ret.empty()) { return "std::string"; }
+    return ret;
+  }
+
+  bool FlexibleStringConstructor(const FieldDef *field) {
+    auto attr = field
+                    ? (field->attributes.Lookup("cpp_str_flex_ctor") != nullptr)
+                    : false;
+    auto ret =
+        attr ? attr : parser_.opts.cpp_object_api_string_flexible_constructor;
+    return ret && NativeString(field) !=
+                      "std::string";  // Only for custom string types.
+  }
+
+  std::string GenTypeNativePtr(const std::string &type, const FieldDef *field,
+                               bool is_constructor) {
+    auto &ptr_type = PtrType(field);
+    if (ptr_type != "naked") {
+      return (ptr_type != "default_ptr_type"
+                  ? ptr_type
+                  : parser_.opts.cpp_object_api_pointer_type) +
+             "<" + type + ">";
+    } else if (is_constructor) {
+      return "";
+    } else {
+      return type + " *";
+    }
+  }
+
+  std::string GenPtrGet(const FieldDef &field) {
+    auto cpp_ptr_type_get = field.attributes.Lookup("cpp_ptr_type_get");
+    if (cpp_ptr_type_get) return cpp_ptr_type_get->constant;
+    auto &ptr_type = PtrType(&field);
+    return ptr_type == "naked" ? "" : ".get()";
+  }
+
+  std::string GenTypeNative(const Type &type, bool invector,
+                            const FieldDef &field) {
+    switch (type.base_type) {
+      case BASE_TYPE_STRING: {
+        return NativeString(&field);
+      }
+      case BASE_TYPE_VECTOR: {
+        const auto type_name = GenTypeNative(type.VectorType(), true, field);
+        if (type.struct_def &&
+            type.struct_def->attributes.Lookup("native_custom_alloc")) {
+          auto native_custom_alloc =
+              type.struct_def->attributes.Lookup("native_custom_alloc");
+          return "std::vector<" + type_name + "," +
+                 native_custom_alloc->constant + "<" + type_name + ">>";
+        } else
+          return "std::vector<" + type_name + ">";
+      }
+      case BASE_TYPE_STRUCT: {
+        auto type_name = WrapInNameSpace(*type.struct_def);
+        if (IsStruct(type)) {
+          auto native_type = type.struct_def->attributes.Lookup("native_type");
+          if (native_type) { type_name = native_type->constant; }
+          if (invector || field.native_inline) {
+            return type_name;
+          } else {
+            return GenTypeNativePtr(type_name, &field, false);
+          }
+        } else {
+          return GenTypeNativePtr(
+              NativeName(type_name, type.struct_def, parser_.opts), &field,
+              false);
+        }
+      }
+      case BASE_TYPE_UNION: {
+        return type.enum_def->name + "Union";
+      }
+      default: { return GenTypeBasic(type, true); }
+    }
+  }
+
+  // Return a C++ type for any type (scalar/pointer) specifically for
+  // using a flatbuffer.
+  std::string GenTypeGet(const Type &type, const char *afterbasic,
+                         const char *beforeptr, const char *afterptr,
+                         bool user_facing_type) {
+    if (IsScalar(type.base_type)) {
+      return GenTypeBasic(type, user_facing_type) + afterbasic;
+    } else if (IsArray(type)) {
+      auto element_type = type.VectorType();
+      return beforeptr +
+             (IsScalar(element_type.base_type)
+                  ? GenTypeBasic(element_type, user_facing_type)
+                  : GenTypePointer(element_type)) +
+             afterptr;
+    } else {
+      return beforeptr + GenTypePointer(type) + afterptr;
+    }
+  }
+
+  std::string GenEnumDecl(const EnumDef &enum_def) const {
+    const IDLOptions &opts = parser_.opts;
+    return (opts.scoped_enums ? "enum class " : "enum ") + Name(enum_def);
+  }
+
+  std::string GenEnumValDecl(const EnumDef &enum_def,
+                             const std::string &enum_val) const {
+    const IDLOptions &opts = parser_.opts;
+    return opts.prefixed_enums ? Name(enum_def) + "_" + enum_val : enum_val;
+  }
+
+  std::string GetEnumValUse(const EnumDef &enum_def,
+                            const EnumVal &enum_val) const {
+    const IDLOptions &opts = parser_.opts;
+    if (opts.scoped_enums) {
+      return Name(enum_def) + "::" + Name(enum_val);
+    } else if (opts.prefixed_enums) {
+      return Name(enum_def) + "_" + Name(enum_val);
+    } else {
+      return Name(enum_val);
+    }
+  }
+
+  std::string StripUnionType(const std::string &name) {
+    return name.substr(0, name.size() - strlen(UnionTypeFieldSuffix()));
+  }
+
+  std::string GetUnionElement(const EnumVal &ev, bool wrap, bool actual_type,
+                              bool native_type = false) {
+    if (ev.union_type.base_type == BASE_TYPE_STRUCT) {
+      auto name = actual_type ? ev.union_type.struct_def->name : Name(ev);
+      return wrap ? WrapInNameSpace(ev.union_type.struct_def->defined_namespace,
+                                    name)
+                  : name;
+    } else if (ev.union_type.base_type == BASE_TYPE_STRING) {
+      return actual_type ? (native_type ? "std::string" : "flatbuffers::String")
+                         : Name(ev);
+    } else {
+      FLATBUFFERS_ASSERT(false);
+      return Name(ev);
+    }
+  }
+
+  std::string UnionVerifySignature(const EnumDef &enum_def) {
+    return "bool Verify" + Name(enum_def) +
+           "(flatbuffers::Verifier &verifier, const void *obj, " +
+           Name(enum_def) + " type)";
+  }
+
+  std::string UnionVectorVerifySignature(const EnumDef &enum_def) {
+    return "bool Verify" + Name(enum_def) + "Vector" +
+           "(flatbuffers::Verifier &verifier, " +
+           "const flatbuffers::Vector<flatbuffers::Offset<void>> *values, " +
+           "const flatbuffers::Vector<uint8_t> *types)";
+  }
+
+  std::string UnionUnPackSignature(const EnumDef &enum_def, bool inclass) {
+    return (inclass ? "static " : "") + std::string("void *") +
+           (inclass ? "" : Name(enum_def) + "Union::") +
+           "UnPack(const void *obj, " + Name(enum_def) +
+           " type, const flatbuffers::resolver_function_t *resolver)";
+  }
+
+  std::string UnionPackSignature(const EnumDef &enum_def, bool inclass) {
+    return "flatbuffers::Offset<void> " +
+           (inclass ? "" : Name(enum_def) + "Union::") +
+           "Pack(flatbuffers::FlatBufferBuilder &_fbb, " +
+           "const flatbuffers::rehasher_function_t *_rehasher" +
+           (inclass ? " = nullptr" : "") + ") const";
+  }
+
+  std::string TableCreateSignature(const StructDef &struct_def, bool predecl,
+                                   const IDLOptions &opts) {
+    return "flatbuffers::Offset<" + Name(struct_def) + "> Create" +
+           Name(struct_def) + "(flatbuffers::FlatBufferBuilder &_fbb, const " +
+           NativeName(Name(struct_def), &struct_def, opts) +
+           " *_o, const flatbuffers::rehasher_function_t *_rehasher" +
+           (predecl ? " = nullptr" : "") + ")";
+  }
+
+  std::string TablePackSignature(const StructDef &struct_def, bool inclass,
+                                 const IDLOptions &opts) {
+    return std::string(inclass ? "static " : "") + "flatbuffers::Offset<" +
+           Name(struct_def) + "> " + (inclass ? "" : Name(struct_def) + "::") +
+           "Pack(flatbuffers::FlatBufferBuilder &_fbb, " + "const " +
+           NativeName(Name(struct_def), &struct_def, opts) + "* _o, " +
+           "const flatbuffers::rehasher_function_t *_rehasher" +
+           (inclass ? " = nullptr" : "") + ")";
+  }
+
+  std::string TableUnPackSignature(const StructDef &struct_def, bool inclass,
+                                   const IDLOptions &opts) {
+    return NativeName(Name(struct_def), &struct_def, opts) + " *" +
+           (inclass ? "" : Name(struct_def) + "::") +
+           "UnPack(const flatbuffers::resolver_function_t *_resolver" +
+           (inclass ? " = nullptr" : "") + ") const";
+  }
+
+  std::string TableUnPackToSignature(const StructDef &struct_def, bool inclass,
+                                     const IDLOptions &opts) {
+    return "void " + (inclass ? "" : Name(struct_def) + "::") + "UnPackTo(" +
+           NativeName(Name(struct_def), &struct_def, opts) + " *" +
+           "_o, const flatbuffers::resolver_function_t *_resolver" +
+           (inclass ? " = nullptr" : "") + ") const";
+  }
+
+  void GenMiniReflectPre(const StructDef *struct_def) {
+    code_.SetValue("NAME", struct_def->name);
+    code_ += "inline const flatbuffers::TypeTable *{{NAME}}TypeTable();";
+    code_ += "";
+  }
+
+  void GenMiniReflect(const StructDef *struct_def, const EnumDef *enum_def) {
+    code_.SetValue("NAME", struct_def ? struct_def->name : enum_def->name);
+    code_.SetValue("SEQ_TYPE",
+                   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->size();
+    code_.SetValue("NUM_FIELDS", NumToString(num_fields));
+    std::vector<std::string> names;
+    std::vector<Type> types;
+
+    if (struct_def) {
+      for (auto it = struct_def->fields.vec.begin();
+           it != struct_def->fields.vec.end(); ++it) {
+        const auto &field = **it;
+        names.push_back(Name(field));
+        types.push_back(field.value.type);
+      }
+    } else {
+      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));
+      }
+    }
+    std::string ts;
+    std::vector<std::string> type_refs;
+    for (auto it = types.begin(); it != types.end(); ++it) {
+      auto &type = *it;
+      if (!ts.empty()) ts += ",\n    ";
+      auto is_vector = type.base_type == BASE_TYPE_VECTOR;
+      auto bt = is_vector ? type.element : type.base_type;
+      auto et = IsScalar(bt) || bt == BASE_TYPE_STRING
+                    ? bt - BASE_TYPE_UTYPE + ET_UTYPE
+                    : ET_SEQUENCE;
+      int ref_idx = -1;
+      std::string ref_name =
+          type.struct_def
+              ? WrapInNameSpace(*type.struct_def)
+              : type.enum_def ? WrapInNameSpace(*type.enum_def) : "";
+      if (!ref_name.empty()) {
+        auto rit = type_refs.begin();
+        for (; rit != type_refs.end(); ++rit) {
+          if (*rit == ref_name) {
+            ref_idx = static_cast<int>(rit - type_refs.begin());
+            break;
+          }
+        }
+        if (rit == type_refs.end()) {
+          ref_idx = static_cast<int>(type_refs.size());
+          type_refs.push_back(ref_name);
+        }
+      }
+      ts += "{ flatbuffers::" + std::string(ElementaryTypeNames()[et]) + ", " +
+            NumToString(is_vector) + ", " + NumToString(ref_idx) + " }";
+    }
+    std::string rs;
+    for (auto it = type_refs.begin(); it != type_refs.end(); ++it) {
+      if (!rs.empty()) rs += ",\n    ";
+      rs += *it + "TypeTable";
+    }
+    std::string ns;
+    for (auto it = names.begin(); it != names.end(); ++it) {
+      if (!ns.empty()) ns += ",\n    ";
+      ns += "\"" + *it + "\"";
+    }
+    std::string vs;
+    const auto consecutive_enum_from_zero =
+        enum_def && enum_def->MinValue()->IsZero() &&
+        ((enum_def->size() - 1) == enum_def->Distance());
+    if (enum_def && !consecutive_enum_from_zero) {
+      for (auto it = enum_def->Vals().begin(); it != enum_def->Vals().end();
+           ++it) {
+        const auto &ev = **it;
+        if (!vs.empty()) vs += ", ";
+        vs += NumToStringCpp(enum_def->ToString(ev),
+                             enum_def->underlying_type.base_type);
+      }
+    } else if (struct_def && struct_def->fixed) {
+      for (auto it = struct_def->fields.vec.begin();
+           it != struct_def->fields.vec.end(); ++it) {
+        const auto &field = **it;
+        vs += NumToString(field.value.offset);
+        vs += ", ";
+      }
+      vs += NumToString(struct_def->bytesize);
+    }
+    code_.SetValue("TYPES", ts);
+    code_.SetValue("REFS", rs);
+    code_.SetValue("NAMES", ns);
+    code_.SetValue("VALUES", vs);
+    code_ += "inline const flatbuffers::TypeTable *{{NAME}}TypeTable() {";
+    if (num_fields) {
+      code_ += "  static const flatbuffers::TypeCode type_codes[] = {";
+      code_ += "    {{TYPES}}";
+      code_ += "  };";
+    }
+    if (!type_refs.empty()) {
+      code_ += "  static const flatbuffers::TypeFunction type_refs[] = {";
+      code_ += "    {{REFS}}";
+      code_ += "  };";
+    }
+    if (!vs.empty()) {
+      // Problem with uint64_t values greater than 9223372036854775807ULL.
+      code_ += "  static const int64_t values[] = { {{VALUES}} };";
+    }
+    auto has_names =
+        num_fields && parser_.opts.mini_reflect == IDLOptions::kTypesAndNames;
+    if (has_names) {
+      code_ += "  static const char * const names[] = {";
+      code_ += "    {{NAMES}}";
+      code_ += "  };";
+    }
+    code_ += "  static const flatbuffers::TypeTable tt = {";
+    code_ += std::string("    flatbuffers::{{SEQ_TYPE}}, {{NUM_FIELDS}}, ") +
+             (num_fields ? "type_codes, " : "nullptr, ") +
+             (!type_refs.empty() ? "type_refs, " : "nullptr, ") +
+             (!vs.empty() ? "values, " : "nullptr, ") +
+             (has_names ? "names" : "nullptr");
+    code_ += "  };";
+    code_ += "  return &tt;";
+    code_ += "}";
+    code_ += "";
+  }
+
+  // Generate an enum declaration,
+  // an enum string lookup table,
+  // and an enum array of values
+
+  void GenEnum(const EnumDef &enum_def) {
+    code_.SetValue("ENUM_NAME", Name(enum_def));
+    code_.SetValue("BASE_TYPE", GenTypeBasic(enum_def.underlying_type, false));
+
+    GenComment(enum_def.doc_comment);
+    code_ += GenEnumDecl(enum_def) + "\\";
+    // MSVC doesn't support int64/uint64 enum without explicitly declared enum
+    // type. The value 4611686018427387904ULL is truncated to zero with warning:
+    // "warning C4309: 'initializing': truncation of constant value".
+    auto add_type = parser_.opts.scoped_enums;
+    add_type |= (enum_def.underlying_type.base_type == BASE_TYPE_LONG);
+    add_type |= (enum_def.underlying_type.base_type == BASE_TYPE_ULONG);
+    if (add_type) code_ += " : {{BASE_TYPE}}\\";
+    code_ += " {";
+
+    code_.SetValue("SEP", ",");
+    auto add_sep = false;
+    for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
+      const auto &ev = **it;
+      if (add_sep) code_ += "{{SEP}}";
+      GenComment(ev.doc_comment, "  ");
+      code_.SetValue("KEY", GenEnumValDecl(enum_def, Name(ev)));
+      code_.SetValue("VALUE",
+                     NumToStringCpp(enum_def.ToString(ev),
+                                    enum_def.underlying_type.base_type));
+      code_ += "  {{KEY}} = {{VALUE}}\\";
+      add_sep = true;
+    }
+    const EnumVal *minv = enum_def.MinValue();
+    const EnumVal *maxv = enum_def.MaxValue();
+
+    if (parser_.opts.scoped_enums || parser_.opts.prefixed_enums) {
+      FLATBUFFERS_ASSERT(minv && maxv);
+
+      code_.SetValue("SEP", ",\n");
+      if (enum_def.attributes.Lookup("bit_flags")) {
+        code_.SetValue("KEY", GenEnumValDecl(enum_def, "NONE"));
+        code_.SetValue("VALUE", "0");
+        code_ += "{{SEP}}  {{KEY}} = {{VALUE}}\\";
+
+        code_.SetValue("KEY", GenEnumValDecl(enum_def, "ANY"));
+        code_.SetValue("VALUE",
+                       NumToStringCpp(enum_def.AllFlags(),
+                                      enum_def.underlying_type.base_type));
+        code_ += "{{SEP}}  {{KEY}} = {{VALUE}}\\";
+      } else {  // MIN & MAX are useless for bit_flags
+        code_.SetValue("KEY", GenEnumValDecl(enum_def, "MIN"));
+        code_.SetValue("VALUE", GenEnumValDecl(enum_def, minv->name));
+        code_ += "{{SEP}}  {{KEY}} = {{VALUE}}\\";
+
+        code_.SetValue("KEY", GenEnumValDecl(enum_def, "MAX"));
+        code_.SetValue("VALUE", GenEnumValDecl(enum_def, maxv->name));
+        code_ += "{{SEP}}  {{KEY}} = {{VALUE}}\\";
+      }
+    }
+    code_ += "";
+    code_ += "};";
+
+    if (parser_.opts.scoped_enums && enum_def.attributes.Lookup("bit_flags")) {
+      code_ +=
+          "FLATBUFFERS_DEFINE_BITMASK_OPERATORS({{ENUM_NAME}}, {{BASE_TYPE}})";
+    }
+    code_ += "";
+
+    // Generate an array of all enumeration values
+    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().begin(); it != enum_def.Vals().end(); ++it) {
+      const auto &ev = **it;
+      auto value = GetEnumValUse(enum_def, ev);
+      auto suffix = *it != enum_def.Vals().back() ? "," : "";
+      code_ += "    " + value + suffix;
+    }
+    code_ += "  };";
+    code_ += "  return values;";
+    code_ += "}";
+    code_ += "";
+
+    // Generate a generate string table for enum values.
+    // Problem is, if values are very sparse that could generate really big
+    // tables. Ideally in that case we generate a map lookup instead, but for
+    // the moment we simply don't output a table at all.
+    auto range = enum_def.Distance();
+    // Average distance between values above which we consider a table
+    // "too sparse". Change at will.
+    static const uint64_t kMaxSparseness = 5;
+    if (range / static_cast<uint64_t>(enum_def.size()) < kMaxSparseness) {
+      code_ += "inline const char * const *EnumNames{{ENUM_NAME}}() {";
+      code_ += "  static const char * const names[" +
+               NumToString(range + 1 + 1) + "] = {";
+
+      auto val = enum_def.Vals().front();
+      for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
+           ++it) {
+        auto ev = *it;
+        for (auto k = enum_def.Distance(val, ev); k > 1; --k) {
+          code_ += "    \"\",";
+        }
+        val = ev;
+        code_ += "    \"" + Name(*ev) + "\",";
+      }
+      code_ += "    nullptr";
+      code_ += "  };";
+
+      code_ += "  return names;";
+      code_ += "}";
+      code_ += "";
+
+      code_ += "inline const char *EnumName{{ENUM_NAME}}({{ENUM_NAME}} e) {";
+
+      code_ += "  if (e < " + GetEnumValUse(enum_def, *enum_def.MinValue()) +
+               " || e > " + GetEnumValUse(enum_def, *enum_def.MaxValue()) +
+               ") return \"\";";
+
+      code_ += "  const size_t index = static_cast<size_t>(e)\\";
+      if (enum_def.MinValue()->IsNonZero()) {
+        auto vals = GetEnumValUse(enum_def, *enum_def.MinValue());
+        code_ += " - static_cast<size_t>(" + vals + ")\\";
+      }
+      code_ += ";";
+
+      code_ += "  return EnumNames{{ENUM_NAME}}()[index];";
+      code_ += "}";
+      code_ += "";
+    } else {
+      code_ += "inline const char *EnumName{{ENUM_NAME}}({{ENUM_NAME}} e) {";
+
+      code_ += "  switch (e) {";
+
+      for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
+           ++it) {
+        const auto &ev = **it;
+        code_ += "    case " + GetEnumValUse(enum_def, ev) + ": return \"" +
+                 Name(ev) + "\";";
+      }
+
+      code_ += "    default: return \"\";";
+      code_ += "  }";
+
+      code_ += "}";
+      code_ += "";
+    }
+
+    // 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().begin(); it != enum_def.Vals().end();
+           ++it) {
+        const auto &ev = **it;
+
+        if (it == enum_def.Vals().begin()) {
+          code_ += "template<typename T> struct {{ENUM_NAME}}Traits {";
+        } else {
+          auto name = GetUnionElement(ev, true, true);
+          code_ += "template<> struct {{ENUM_NAME}}Traits<" + name + "> {";
+        }
+
+        auto value = GetEnumValUse(enum_def, ev);
+        code_ += "  static const {{ENUM_NAME}} enum_value = " + value + ";";
+        code_ += "};";
+        code_ += "";
+      }
+    }
+
+    if (parser_.opts.generate_object_based_api && enum_def.is_union) {
+      // Generate a union type
+      code_.SetValue("NAME", Name(enum_def));
+      FLATBUFFERS_ASSERT(enum_def.Lookup("NONE"));
+      code_.SetValue("NONE", GetEnumValUse(enum_def, *enum_def.Lookup("NONE")));
+
+      code_ += "struct {{NAME}}Union {";
+      code_ += "  {{NAME}} type;";
+      code_ += "  void *value;";
+      code_ += "";
+      code_ += "  {{NAME}}Union() : type({{NONE}}), value(nullptr) {}";
+      code_ += "  {{NAME}}Union({{NAME}}Union&& u) FLATBUFFERS_NOEXCEPT :";
+      code_ += "    type({{NONE}}), value(nullptr)";
+      code_ += "    { std::swap(type, u.type); std::swap(value, u.value); }";
+      code_ += "  {{NAME}}Union(const {{NAME}}Union &) FLATBUFFERS_NOEXCEPT;";
+      code_ +=
+          "  {{NAME}}Union &operator=(const {{NAME}}Union &u) "
+          "FLATBUFFERS_NOEXCEPT";
+      code_ +=
+          "    { {{NAME}}Union t(u); std::swap(type, t.type); std::swap(value, "
+          "t.value); return *this; }";
+      code_ +=
+          "  {{NAME}}Union &operator=({{NAME}}Union &&u) FLATBUFFERS_NOEXCEPT";
+      code_ +=
+          "    { std::swap(type, u.type); std::swap(value, u.value); return "
+          "*this; }";
+      code_ += "  ~{{NAME}}Union() { Reset(); }";
+      code_ += "";
+      code_ += "  void Reset();";
+      code_ += "";
+      if (!enum_def.uses_multiple_type_instances) {
+        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 RT::TableType>::enum_value;";
+        code_ += "    if (type != {{NONE}}) {";
+        code_ += "      value = new RT(std::forward<T>(val));";
+        code_ += "    }";
+        code_ += "  }";
+        code_ += "#endif  // FLATBUFFERS_CPP98_STL";
+        code_ += "";
+      }
+      code_ += "  " + UnionUnPackSignature(enum_def, true) + ";";
+      code_ += "  " + UnionPackSignature(enum_def, true) + ";";
+      code_ += "";
+
+      for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
+           ++it) {
+        const auto &ev = **it;
+        if (ev.IsZero()) { continue; }
+
+        const auto native_type =
+            NativeName(GetUnionElement(ev, true, true, true),
+                       ev.union_type.struct_def, parser_.opts);
+        code_.SetValue("NATIVE_TYPE", native_type);
+        code_.SetValue("NATIVE_NAME", Name(ev));
+        code_.SetValue("NATIVE_ID", GetEnumValUse(enum_def, ev));
+
+        code_ += "  {{NATIVE_TYPE}} *As{{NATIVE_NAME}}() {";
+        code_ += "    return type == {{NATIVE_ID}} ?";
+        code_ += "      reinterpret_cast<{{NATIVE_TYPE}} *>(value) : nullptr;";
+        code_ += "  }";
+
+        code_ += "  const {{NATIVE_TYPE}} *As{{NATIVE_NAME}}() const {";
+        code_ += "    return type == {{NATIVE_ID}} ?";
+        code_ +=
+            "      reinterpret_cast<const {{NATIVE_TYPE}} *>(value) : nullptr;";
+        code_ += "  }";
+      }
+      code_ += "};";
+      code_ += "";
+
+      if (parser_.opts.gen_compare) {
+        code_ += "";
+        code_ +=
+            "inline bool operator==(const {{NAME}}Union &lhs, const "
+            "{{NAME}}Union &rhs) {";
+        code_ += "  if (lhs.type != rhs.type) return false;";
+        code_ += "  switch (lhs.type) {";
+
+        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.IsNonZero()) {
+            const auto native_type =
+                NativeName(GetUnionElement(ev, true, true, true),
+                           ev.union_type.struct_def, parser_.opts);
+            code_.SetValue("NATIVE_TYPE", native_type);
+            code_ += "    case {{NATIVE_ID}}: {";
+            code_ +=
+                "      return *(reinterpret_cast<const {{NATIVE_TYPE}} "
+                "*>(lhs.value)) ==";
+            code_ +=
+                "             *(reinterpret_cast<const {{NATIVE_TYPE}} "
+                "*>(rhs.value));";
+            code_ += "    }";
+          } else {
+            code_ += "    case {{NATIVE_ID}}: {";
+            code_ += "      return true;";  // "NONE" enum value.
+            code_ += "    }";
+          }
+        }
+        code_ += "    default: {";
+        code_ += "      return false;";
+        code_ += "    }";
+        code_ += "  }";
+        code_ += "}";
+
+        code_ += "";
+        code_ +=
+            "inline bool operator!=(const {{NAME}}Union &lhs, const "
+            "{{NAME}}Union &rhs) {";
+        code_ += "    return !(lhs == rhs);";
+        code_ += "}";
+        code_ += "";
+      }
+    }
+
+    if (enum_def.is_union) {
+      code_ += UnionVerifySignature(enum_def) + ";";
+      code_ += UnionVectorVerifySignature(enum_def) + ";";
+      code_ += "";
+    }
+  }
+
+  void GenUnionPost(const EnumDef &enum_def) {
+    // Generate a verifier function for this union that can be called by the
+    // table verifier functions. It uses a switch case to select a specific
+    // verifier function to call, this should be safe even if the union type
+    // has been corrupted, since the verifiers will simply fail when called
+    // on the wrong type.
+    code_.SetValue("ENUM_NAME", Name(enum_def));
+
+    code_ += "inline " + UnionVerifySignature(enum_def) + " {";
+    code_ += "  switch (type) {";
+    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.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 verifier.Verify<{{TYPE}}>(static_cast<const "
+                     "uint8_t *>(obj), 0);";
+          } else {
+            code_ += getptr;
+            code_ += "      return verifier.VerifyTable(ptr);";
+          }
+        } else if (ev.union_type.base_type == BASE_TYPE_STRING) {
+          code_ += getptr;
+          code_ += "      return verifier.VerifyString(ptr);";
+        } else {
+          FLATBUFFERS_ASSERT(false);
+        }
+        code_ += "    }";
+      } else {
+        code_ += "    case {{LABEL}}: {";
+        code_ += "      return true;";  // "NONE" enum value.
+        code_ += "    }";
+      }
+    }
+    code_ += "    default: return false;";
+    code_ += "  }";
+    code_ += "}";
+    code_ += "";
+
+    code_ += "inline " + UnionVectorVerifySignature(enum_def) + " {";
+    code_ += "  if (!values || !types) return !values && !types;";
+    code_ += "  if (values->size() != types->size()) return false;";
+    code_ += "  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {";
+    code_ += "    if (!Verify" + Name(enum_def) + "(";
+    code_ += "        verifier,  values->Get(i), types->GetEnum<" +
+             Name(enum_def) + ">(i))) {";
+    code_ += "      return false;";
+    code_ += "    }";
+    code_ += "  }";
+    code_ += "  return true;";
+    code_ += "}";
+    code_ += "";
+
+    if (parser_.opts.generate_object_based_api) {
+      // Generate union Unpack() and Pack() functions.
+      code_ += "inline " + UnionUnPackSignature(enum_def, false) + " {";
+      code_ += "  switch (type) {";
+      for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
+           ++it) {
+        const auto &ev = **it;
+        if (ev.IsZero()) { continue; }
+
+        code_.SetValue("LABEL", GetEnumValUse(enum_def, ev));
+        code_.SetValue("TYPE", GetUnionElement(ev, true, true));
+        code_ += "    case {{LABEL}}: {";
+        code_ += "      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 new " +
+                     WrapInNameSpace(*ev.union_type.struct_def) + "(*ptr);";
+          } else {
+            code_ += "      return ptr->UnPack(resolver);";
+          }
+        } else if (ev.union_type.base_type == BASE_TYPE_STRING) {
+          code_ += "      return new std::string(ptr->c_str(), ptr->size());";
+        } else {
+          FLATBUFFERS_ASSERT(false);
+        }
+        code_ += "    }";
+      }
+      code_ += "    default: return nullptr;";
+      code_ += "  }";
+      code_ += "}";
+      code_ += "";
+
+      code_ += "inline " + UnionPackSignature(enum_def, false) + " {";
+      code_ += "  switch (type) {";
+      for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
+           ++it) {
+        auto &ev = **it;
+        if (ev.IsZero()) { continue; }
+
+        code_.SetValue("LABEL", GetEnumValUse(enum_def, ev));
+        code_.SetValue("TYPE",
+                       NativeName(GetUnionElement(ev, true, true, true),
+                                  ev.union_type.struct_def, parser_.opts));
+        code_.SetValue("NAME", GetUnionElement(ev, false, true));
+        code_ += "    case {{LABEL}}: {";
+        code_ += "      auto ptr = reinterpret_cast<const {{TYPE}} *>(value);";
+        if (ev.union_type.base_type == BASE_TYPE_STRUCT) {
+          if (ev.union_type.struct_def->fixed) {
+            code_ += "      return _fbb.CreateStruct(*ptr).Union();";
+          } else {
+            code_ +=
+                "      return Create{{NAME}}(_fbb, ptr, _rehasher).Union();";
+          }
+        } else if (ev.union_type.base_type == BASE_TYPE_STRING) {
+          code_ += "      return _fbb.CreateString(*ptr).Union();";
+        } else {
+          FLATBUFFERS_ASSERT(false);
+        }
+        code_ += "    }";
+      }
+      code_ += "    default: return 0;";
+      code_ += "  }";
+      code_ += "}";
+      code_ += "";
+
+      // Union copy constructor
+      code_ +=
+          "inline {{ENUM_NAME}}Union::{{ENUM_NAME}}Union(const "
+          "{{ENUM_NAME}}Union &u) FLATBUFFERS_NOEXCEPT : type(u.type), "
+          "value(nullptr) {";
+      code_ += "  switch (type) {";
+      for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
+           ++it) {
+        const auto &ev = **it;
+        if (ev.IsZero()) { continue; }
+        code_.SetValue("LABEL", GetEnumValUse(enum_def, ev));
+        code_.SetValue("TYPE",
+                       NativeName(GetUnionElement(ev, true, true, true),
+                                  ev.union_type.struct_def, parser_.opts));
+        code_ += "    case {{LABEL}}: {";
+        bool copyable = true;
+        if (ev.union_type.base_type == BASE_TYPE_STRUCT) {
+          // Don't generate code to copy if table is not copyable.
+          // TODO(wvo): make tables copyable instead.
+          for (auto fit = ev.union_type.struct_def->fields.vec.begin();
+               fit != ev.union_type.struct_def->fields.vec.end(); ++fit) {
+            const auto &field = **fit;
+            if (!field.deprecated && field.value.type.struct_def &&
+                !field.native_inline) {
+              copyable = false;
+              break;
+            }
+          }
+        }
+        if (copyable) {
+          code_ +=
+              "      value = new {{TYPE}}(*reinterpret_cast<{{TYPE}} *>"
+              "(u.value));";
+        } else {
+          code_ +=
+              "      FLATBUFFERS_ASSERT(false);  // {{TYPE}} not copyable.";
+        }
+        code_ += "      break;";
+        code_ += "    }";
+      }
+      code_ += "    default:";
+      code_ += "      break;";
+      code_ += "  }";
+      code_ += "}";
+      code_ += "";
+
+      // Union Reset() function.
+      FLATBUFFERS_ASSERT(enum_def.Lookup("NONE"));
+      code_.SetValue("NONE", GetEnumValUse(enum_def, *enum_def.Lookup("NONE")));
+
+      code_ += "inline void {{ENUM_NAME}}Union::Reset() {";
+      code_ += "  switch (type) {";
+      for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
+           ++it) {
+        const auto &ev = **it;
+        if (ev.IsZero()) { continue; }
+        code_.SetValue("LABEL", GetEnumValUse(enum_def, ev));
+        code_.SetValue("TYPE",
+                       NativeName(GetUnionElement(ev, true, true, true),
+                                  ev.union_type.struct_def, parser_.opts));
+        code_ += "    case {{LABEL}}: {";
+        code_ += "      auto ptr = reinterpret_cast<{{TYPE}} *>(value);";
+        code_ += "      delete ptr;";
+        code_ += "      break;";
+        code_ += "    }";
+      }
+      code_ += "    default: break;";
+      code_ += "  }";
+      code_ += "  value = nullptr;";
+      code_ += "  type = {{NONE}};";
+      code_ += "}";
+      code_ += "";
+    }
+  }
+
+  // Generates a value with optionally a cast applied if the field has a
+  // different underlying type from its interface type (currently only the
+  // case for enums. "from" specify the direction, true meaning from the
+  // underlying type to the interface type.
+  std::string GenUnderlyingCast(const FieldDef &field, bool from,
+                                const std::string &val) {
+    if (from && field.value.type.base_type == BASE_TYPE_BOOL) {
+      return val + " != 0";
+    } else if ((field.value.type.enum_def &&
+                IsScalar(field.value.type.base_type)) ||
+               field.value.type.base_type == BASE_TYPE_BOOL) {
+      return "static_cast<" + GenTypeBasic(field.value.type, from) + ">(" +
+             val + ")";
+    } else {
+      return val;
+    }
+  }
+
+  std::string GenFieldOffsetName(const FieldDef &field) {
+    std::string uname = Name(field);
+    std::transform(uname.begin(), uname.end(), uname.begin(), ToUpper);
+    return "VT_" + uname;
+  }
+
+  void GenFullyQualifiedNameGetter(const StructDef &struct_def,
+                                   const std::string &name) {
+    if (!parser_.opts.generate_name_strings) { return; }
+    auto fullname = struct_def.defined_namespace->GetFullyQualifiedName(name);
+    code_.SetValue("NAME", fullname);
+    code_.SetValue("CONSTEXPR", "FLATBUFFERS_CONSTEXPR");
+    code_ += "  static {{CONSTEXPR}} const char *GetFullyQualifiedName() {";
+    code_ += "    return \"{{NAME}}\";";
+    code_ += "  }";
+  }
+
+  std::string GenDefaultConstant(const FieldDef &field) {
+    if (IsFloat(field.value.type.base_type))
+      return float_const_gen_.GenFloatConstant(field);
+    else
+      return NumToStringCpp(field.value.constant, field.value.type.base_type);
+  }
+
+  std::string GetDefaultScalarValue(const FieldDef &field, bool is_ctor) {
+    if (field.value.type.enum_def && IsScalar(field.value.type.base_type)) {
+      auto ev = field.value.type.enum_def->FindByValue(field.value.constant);
+      if (ev) {
+        return WrapInNameSpace(field.value.type.enum_def->defined_namespace,
+                               GetEnumValUse(*field.value.type.enum_def, *ev));
+      } else {
+        return GenUnderlyingCast(
+            field, true,
+            NumToStringCpp(field.value.constant, field.value.type.base_type));
+      }
+    } else if (field.value.type.base_type == BASE_TYPE_BOOL) {
+      return field.value.constant == "0" ? "false" : "true";
+    } else if (field.attributes.Lookup("cpp_type")) {
+      if (is_ctor) {
+        if (PtrType(&field) == "naked") {
+          return "nullptr";
+        } else {
+          return "";
+        }
+      } else {
+        return "0";
+      }
+    } else {
+      return GenDefaultConstant(field);
+    }
+  }
+
+  void GenParam(const FieldDef &field, bool direct, const char *prefix) {
+    code_.SetValue("PRE", prefix);
+    code_.SetValue("PARAM_NAME", Name(field));
+    if (direct && field.value.type.base_type == BASE_TYPE_STRING) {
+      code_.SetValue("PARAM_TYPE", "const char *");
+      code_.SetValue("PARAM_VALUE", "nullptr");
+    } else if (direct && field.value.type.base_type == BASE_TYPE_VECTOR) {
+      const auto vtype = field.value.type.VectorType();
+      std::string type;
+      if (IsStruct(vtype)) {
+        type = WrapInNameSpace(*vtype.struct_def);
+      } else {
+        type = GenTypeWire(vtype, "", false);
+      }
+      code_.SetValue("PARAM_TYPE", "const std::vector<" + type + "> *");
+      code_.SetValue("PARAM_VALUE", "nullptr");
+    } else {
+      code_.SetValue("PARAM_TYPE", GenTypeWire(field.value.type, " ", true));
+      code_.SetValue("PARAM_VALUE", GetDefaultScalarValue(field, false));
+    }
+    code_ += "{{PRE}}{{PARAM_TYPE}}{{PARAM_NAME}} = {{PARAM_VALUE}}\\";
+  }
+
+  // Generate a member, including a default value for scalars and raw pointers.
+  void GenMember(const FieldDef &field) {
+    if (!field.deprecated &&  // Deprecated fields won't be accessible.
+        field.value.type.base_type != BASE_TYPE_UTYPE &&
+        (field.value.type.base_type != BASE_TYPE_VECTOR ||
+         field.value.type.element != BASE_TYPE_UTYPE)) {
+      auto type = GenTypeNative(field.value.type, false, field);
+      auto cpp_type = field.attributes.Lookup("cpp_type");
+      auto full_type =
+          (cpp_type
+               ? (field.value.type.base_type == BASE_TYPE_VECTOR
+                      ? "std::vector<" +
+                            GenTypeNativePtr(cpp_type->constant, &field,
+                                             false) +
+                            "> "
+                      : GenTypeNativePtr(cpp_type->constant, &field, false))
+               : type + " ");
+      code_.SetValue("FIELD_TYPE", full_type);
+      code_.SetValue("FIELD_NAME", Name(field));
+      code_ += "  {{FIELD_TYPE}}{{FIELD_NAME}};";
+    }
+  }
+
+  // Generate the default constructor for this struct. Properly initialize all
+  // scalar members with default values.
+  void GenDefaultConstructor(const StructDef &struct_def) {
+    std::string initializer_list;
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+      if (!field.deprecated &&  // Deprecated fields won't be accessible.
+          field.value.type.base_type != BASE_TYPE_UTYPE) {
+        auto cpp_type = field.attributes.Lookup("cpp_type");
+        auto native_default = field.attributes.Lookup("native_default");
+        // Scalar types get parsed defaults, raw pointers get nullptrs.
+        if (IsScalar(field.value.type.base_type)) {
+          if (!initializer_list.empty()) { initializer_list += ",\n        "; }
+          initializer_list += Name(field);
+          initializer_list +=
+              "(" +
+              (native_default ? std::string(native_default->constant)
+                              : GetDefaultScalarValue(field, true)) +
+              ")";
+        } else if (field.value.type.base_type == BASE_TYPE_STRUCT) {
+          if (IsStruct(field.value.type)) {
+            if (native_default) {
+              if (!initializer_list.empty()) {
+                initializer_list += ",\n        ";
+              }
+              initializer_list +=
+                  Name(field) + "(" + native_default->constant + ")";
+            }
+          }
+        } else if (cpp_type && field.value.type.base_type != BASE_TYPE_VECTOR) {
+          if (!initializer_list.empty()) { initializer_list += ",\n        "; }
+          initializer_list += Name(field) + "(0)";
+        }
+      }
+    }
+    if (!initializer_list.empty()) {
+      initializer_list = "\n      : " + initializer_list;
+    }
+
+    code_.SetValue("NATIVE_NAME",
+                   NativeName(Name(struct_def), &struct_def, parser_.opts));
+    code_.SetValue("INIT_LIST", initializer_list);
+
+    code_ += "  {{NATIVE_NAME}}(){{INIT_LIST}} {";
+    code_ += "  }";
+  }
+
+  void GenCompareOperator(const StructDef &struct_def,
+                          std::string accessSuffix = "") {
+    std::string compare_op;
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+      if (!field.deprecated &&  // Deprecated fields won't be accessible.
+          field.value.type.base_type != BASE_TYPE_UTYPE &&
+          (field.value.type.base_type != BASE_TYPE_VECTOR ||
+           field.value.type.element != BASE_TYPE_UTYPE)) {
+        if (!compare_op.empty()) { compare_op += " &&\n      "; }
+        auto accessor = Name(field) + accessSuffix;
+        compare_op += "(lhs." + accessor + " == rhs." + accessor + ")";
+      }
+    }
+
+    std::string cmp_lhs;
+    std::string cmp_rhs;
+    if (compare_op.empty()) {
+      cmp_lhs = "";
+      cmp_rhs = "";
+      compare_op = "  return true;";
+    } else {
+      cmp_lhs = "lhs";
+      cmp_rhs = "rhs";
+      compare_op = "  return\n      " + compare_op + ";";
+    }
+
+    code_.SetValue("CMP_OP", compare_op);
+    code_.SetValue("CMP_LHS", cmp_lhs);
+    code_.SetValue("CMP_RHS", cmp_rhs);
+    code_ += "";
+    code_ +=
+        "inline bool operator==(const {{NATIVE_NAME}} &{{CMP_LHS}}, const "
+        "{{NATIVE_NAME}} &{{CMP_RHS}}) {";
+    code_ += "{{CMP_OP}}";
+    code_ += "}";
+
+    code_ += "";
+    code_ +=
+        "inline bool operator!=(const {{NATIVE_NAME}} &lhs, const "
+        "{{NATIVE_NAME}} &rhs) {";
+    code_ += "    return !(lhs == rhs);";
+    code_ += "}";
+    code_ += "";
+  }
+
+  void GenOperatorNewDelete(const StructDef &struct_def) {
+    if (auto native_custom_alloc =
+            struct_def.attributes.Lookup("native_custom_alloc")) {
+      code_ += "  inline void *operator new (std::size_t count) {";
+      code_ += "    return " + native_custom_alloc->constant +
+               "<{{NATIVE_NAME}}>().allocate(count / sizeof({{NATIVE_NAME}}));";
+      code_ += "  }";
+      code_ += "  inline void operator delete (void *ptr) {";
+      code_ += "    return " + native_custom_alloc->constant +
+               "<{{NATIVE_NAME}}>().deallocate(static_cast<{{NATIVE_NAME}}*>("
+               "ptr),1);";
+      code_ += "  }";
+    }
+  }
+
+  void GenNativeTable(const StructDef &struct_def) {
+    const auto native_name =
+        NativeName(Name(struct_def), &struct_def, parser_.opts);
+    code_.SetValue("STRUCT_NAME", Name(struct_def));
+    code_.SetValue("NATIVE_NAME", native_name);
+
+    // Generate a C++ object that can hold an unpacked version of this table.
+    code_ += "struct {{NATIVE_NAME}} : public flatbuffers::NativeTable {";
+    code_ += "  typedef {{STRUCT_NAME}} TableType;";
+    GenFullyQualifiedNameGetter(struct_def, native_name);
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      GenMember(**it);
+    }
+    GenOperatorNewDelete(struct_def);
+    GenDefaultConstructor(struct_def);
+    code_ += "};";
+    if (parser_.opts.gen_compare) GenCompareOperator(struct_def);
+    code_ += "";
+  }
+
+  // Generate the code to call the appropriate Verify function(s) for a field.
+  void GenVerifyCall(const FieldDef &field, const char *prefix) {
+    code_.SetValue("PRE", prefix);
+    code_.SetValue("NAME", Name(field));
+    code_.SetValue("REQUIRED", field.required ? "Required" : "");
+    code_.SetValue("SIZE", GenTypeSize(field.value.type));
+    code_.SetValue("OFFSET", GenFieldOffsetName(field));
+    if (IsScalar(field.value.type.base_type) || IsStruct(field.value.type)) {
+      code_ +=
+          "{{PRE}}VerifyField{{REQUIRED}}<{{SIZE}}>(verifier, {{OFFSET}})\\";
+    } else {
+      code_ += "{{PRE}}VerifyOffset{{REQUIRED}}(verifier, {{OFFSET}})\\";
+    }
+
+    switch (field.value.type.base_type) {
+      case BASE_TYPE_UNION: {
+        code_.SetValue("ENUM_NAME", field.value.type.enum_def->name);
+        code_.SetValue("SUFFIX", UnionTypeFieldSuffix());
+        code_ +=
+            "{{PRE}}Verify{{ENUM_NAME}}(verifier, {{NAME}}(), "
+            "{{NAME}}{{SUFFIX}}())\\";
+        break;
+      }
+      case BASE_TYPE_STRUCT: {
+        if (!field.value.type.struct_def->fixed) {
+          code_ += "{{PRE}}verifier.VerifyTable({{NAME}}())\\";
+        }
+        break;
+      }
+      case BASE_TYPE_STRING: {
+        code_ += "{{PRE}}verifier.VerifyString({{NAME}}())\\";
+        break;
+      }
+      case BASE_TYPE_VECTOR: {
+        code_ += "{{PRE}}verifier.VerifyVector({{NAME}}())\\";
+
+        switch (field.value.type.element) {
+          case BASE_TYPE_STRING: {
+            code_ += "{{PRE}}verifier.VerifyVectorOfStrings({{NAME}}())\\";
+            break;
+          }
+          case BASE_TYPE_STRUCT: {
+            if (!field.value.type.struct_def->fixed) {
+              code_ += "{{PRE}}verifier.VerifyVectorOfTables({{NAME}}())\\";
+            }
+            break;
+          }
+          case BASE_TYPE_UNION: {
+            code_.SetValue("ENUM_NAME", field.value.type.enum_def->name);
+            code_ +=
+                "{{PRE}}Verify{{ENUM_NAME}}Vector(verifier, {{NAME}}(), "
+                "{{NAME}}_type())\\";
+            break;
+          }
+          default: break;
+        }
+        break;
+      }
+      default: { break; }
+    }
+  }
+
+  // Generate CompareWithValue method for a key field.
+  void GenKeyFieldMethods(const FieldDef &field) {
+    FLATBUFFERS_ASSERT(field.key);
+    const bool is_string = (field.value.type.base_type == BASE_TYPE_STRING);
+
+    code_ += "  bool KeyCompareLessThan(const {{STRUCT_NAME}} *o) const {";
+    if (is_string) {
+      // use operator< of flatbuffers::String
+      code_ += "    return *{{FIELD_NAME}}() < *o->{{FIELD_NAME}}();";
+    } else {
+      code_ += "    return {{FIELD_NAME}}() < o->{{FIELD_NAME}}();";
+    }
+    code_ += "  }";
+
+    if (is_string) {
+      code_ += "  int KeyCompareWithValue(const char *val) const {";
+      code_ += "    return strcmp({{FIELD_NAME}}()->c_str(), val);";
+      code_ += "  }";
+    } else {
+      FLATBUFFERS_ASSERT(IsScalar(field.value.type.base_type));
+      auto type = GenTypeBasic(field.value.type, false);
+      if (parser_.opts.scoped_enums && field.value.type.enum_def &&
+          IsScalar(field.value.type.base_type)) {
+        type = GenTypeGet(field.value.type, " ", "const ", " *", true);
+      }
+      // Returns {field<val: -1, field==val: 0, field>val: +1}.
+      code_.SetValue("KEY_TYPE", type);
+      code_ += "  int KeyCompareWithValue({{KEY_TYPE}} val) const {";
+      code_ +=
+          "    return static_cast<int>({{FIELD_NAME}}() > val) - "
+          "static_cast<int>({{FIELD_NAME}}() < val);";
+      code_ += "  }";
+    }
+  }
+
+  // Generate an accessor struct, builder structs & function for a table.
+  void GenTable(const StructDef &struct_def) {
+    if (parser_.opts.generate_object_based_api) { GenNativeTable(struct_def); }
+
+    // Generate an accessor struct, with methods of the form:
+    // type name() const { return GetField<type>(offset, defaultval); }
+    GenComment(struct_def.doc_comment);
+
+    code_.SetValue("STRUCT_NAME", Name(struct_def));
+    code_ +=
+        "struct {{STRUCT_NAME}} FLATBUFFERS_FINAL_CLASS"
+        " : private flatbuffers::Table {";
+    if (parser_.opts.generate_object_based_api) {
+      code_ += "  typedef {{NATIVE_NAME}} NativeTableType;";
+    }
+    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 field id constants.
+    if (struct_def.fields.vec.size() > 0) {
+      // We need to add a trailing comma to all elements except the last one as
+      // older versions of gcc complain about this.
+      code_.SetValue("SEP", "");
+      code_ +=
+          "  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {";
+      for (auto it = struct_def.fields.vec.begin();
+           it != struct_def.fields.vec.end(); ++it) {
+        const auto &field = **it;
+        if (field.deprecated) {
+          // Deprecated fields won't be accessible.
+          continue;
+        }
+
+        code_.SetValue("OFFSET_NAME", GenFieldOffsetName(field));
+        code_.SetValue("OFFSET_VALUE", NumToString(field.value.offset));
+        code_ += "{{SEP}}    {{OFFSET_NAME}} = {{OFFSET_VALUE}}\\";
+        code_.SetValue("SEP", ",\n");
+      }
+      code_ += "";
+      code_ += "  };";
+    }
+
+    // Generate the accessors.
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+      if (field.deprecated) {
+        // Deprecated fields won't be accessible.
+        continue;
+      }
+
+      const bool is_struct = IsStruct(field.value.type);
+      const bool is_scalar = IsScalar(field.value.type.base_type);
+      code_.SetValue("FIELD_NAME", Name(field));
+
+      // Call a different accessor for pointers, that indirects.
+      std::string accessor = "";
+      if (is_scalar) {
+        accessor = "GetField<";
+      } else if (is_struct) {
+        accessor = "GetStruct<";
+      } else {
+        accessor = "GetPointer<";
+      }
+      auto offset_str = GenFieldOffsetName(field);
+      auto offset_type =
+          GenTypeGet(field.value.type, "", "const ", " *", false);
+
+      auto call = accessor + offset_type + ">(" + offset_str;
+      // Default value as second arg for non-pointer types.
+      if (is_scalar) { call += ", " + GenDefaultConstant(field); }
+      call += ")";
+
+      std::string afterptr = " *" + NullableExtension();
+      GenComment(field.doc_comment, "  ");
+      code_.SetValue("FIELD_TYPE", GenTypeGet(field.value.type, " ", "const ",
+                                              afterptr.c_str(), true));
+      code_.SetValue("FIELD_VALUE", GenUnderlyingCast(field, true, call));
+      code_.SetValue("NULLABLE_EXT", NullableExtension());
+
+      code_ += "  {{FIELD_TYPE}}{{FIELD_NAME}}() const {";
+      code_ += "    return {{FIELD_VALUE}};";
+      code_ += "  }";
+
+      if (field.value.type.base_type == BASE_TYPE_UNION) {
+        auto u = field.value.type.enum_def;
+
+        if (!field.value.type.enum_def->uses_multiple_type_instances)
+          code_ +=
+              "  template<typename T> "
+              "const T *{{NULLABLE_EXT}}{{FIELD_NAME}}_as() const;";
+
+        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);
+
+          // @TODO: Mby make this decisions more universal? How?
+          code_.SetValue("U_GET_TYPE",
+                         EscapeKeyword(field.name + UnionTypeFieldSuffix()));
+          code_.SetValue(
+              "U_ELEMENT_TYPE",
+              WrapInNameSpace(u->defined_namespace, GetEnumValUse(*u, ev)));
+          code_.SetValue("U_FIELD_TYPE", "const " + full_struct_name + " *");
+          code_.SetValue("U_FIELD_NAME", Name(field) + "_as_" + Name(ev));
+          code_.SetValue("U_NULLABLE", NullableExtension());
+
+          // `const Type *union_name_asType() const` accessor.
+          code_ += "  {{U_FIELD_TYPE}}{{U_NULLABLE}}{{U_FIELD_NAME}}() const {";
+          code_ +=
+              "    return {{U_GET_TYPE}}() == {{U_ELEMENT_TYPE}} ? "
+              "static_cast<{{U_FIELD_TYPE}}>({{FIELD_NAME}}()) "
+              ": nullptr;";
+          code_ += "  }";
+        }
+      }
+
+      if (parser_.opts.mutable_buffer) {
+        if (is_scalar) {
+          const auto type = GenTypeWire(field.value.type, "", false);
+          code_.SetValue("SET_FN", "SetField<" + type + ">");
+          code_.SetValue("OFFSET_NAME", offset_str);
+          code_.SetValue("FIELD_TYPE", GenTypeBasic(field.value.type, true));
+          code_.SetValue("FIELD_VALUE",
+                         GenUnderlyingCast(field, false, "_" + Name(field)));
+          code_.SetValue("DEFAULT_VALUE", GenDefaultConstant(field));
+
+          code_ +=
+              "  bool mutate_{{FIELD_NAME}}({{FIELD_TYPE}} "
+              "_{{FIELD_NAME}}) {";
+          code_ +=
+              "    return {{SET_FN}}({{OFFSET_NAME}}, {{FIELD_VALUE}}, "
+              "{{DEFAULT_VALUE}});";
+          code_ += "  }";
+        } else {
+          auto postptr = " *" + NullableExtension();
+          auto type =
+              GenTypeGet(field.value.type, " ", "", postptr.c_str(), true);
+          auto underlying = accessor + type + ">(" + offset_str + ")";
+          code_.SetValue("FIELD_TYPE", type);
+          code_.SetValue("FIELD_VALUE",
+                         GenUnderlyingCast(field, true, underlying));
+
+          code_ += "  {{FIELD_TYPE}}mutable_{{FIELD_NAME}}() {";
+          code_ += "    return {{FIELD_VALUE}};";
+          code_ += "  }";
+        }
+      }
+
+      auto nested = field.attributes.Lookup("nested_flatbuffer");
+      if (nested) {
+        std::string qualified_name = nested->constant;
+        auto nested_root = parser_.LookupStruct(nested->constant);
+        if (nested_root == nullptr) {
+          qualified_name = parser_.current_namespace_->GetFullyQualifiedName(
+              nested->constant);
+          nested_root = parser_.LookupStruct(qualified_name);
+        }
+        FLATBUFFERS_ASSERT(nested_root);  // Guaranteed to exist by parser.
+        (void)nested_root;
+        code_.SetValue("CPP_NAME", TranslateNameSpace(qualified_name));
+
+        code_ += "  const {{CPP_NAME}} *{{FIELD_NAME}}_nested_root() const {";
+        code_ +=
+            "    return "
+            "flatbuffers::GetRoot<{{CPP_NAME}}>({{FIELD_NAME}}()->Data());";
+        code_ += "  }";
+      }
+
+      if (field.flexbuffer) {
+        code_ +=
+            "  flexbuffers::Reference {{FIELD_NAME}}_flexbuffer_root()"
+            " const {";
+        // Both Data() and size() are const-methods, therefore call order
+        // doesn't matter.
+        code_ +=
+            "    return flexbuffers::GetRoot({{FIELD_NAME}}()->Data(), "
+            "{{FIELD_NAME}}()->size());";
+        code_ += "  }";
+      }
+
+      // Generate a comparison function for this field if it is a key.
+      if (field.key) { GenKeyFieldMethods(field); }
+    }
+
+    // Generate a verifier function that can check a buffer from an untrusted
+    // source will never cause reads outside the buffer.
+    code_ += "  bool Verify(flatbuffers::Verifier &verifier) const {";
+    code_ += "    return VerifyTableStart(verifier)\\";
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+      if (field.deprecated) { continue; }
+      GenVerifyCall(field, " &&\n           ");
+    }
+
+    code_ += " &&\n           verifier.EndTable();";
+    code_ += "  }";
+
+    if (parser_.opts.generate_object_based_api) {
+      // Generate the UnPack() pre declaration.
+      code_ +=
+          "  " + TableUnPackSignature(struct_def, true, parser_.opts) + ";";
+      code_ +=
+          "  " + TableUnPackToSignature(struct_def, true, parser_.opts) + ";";
+      code_ += "  " + TablePackSignature(struct_def, true, parser_.opts) + ";";
+    }
+
+    code_ += "};";  // End of table.
+    code_ += "";
+
+    // Explicit specializations for union accessors
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+      if (field.deprecated || field.value.type.base_type != BASE_TYPE_UNION) {
+        continue;
+      }
+
+      auto u = field.value.type.enum_def;
+      if (u->uses_multiple_type_instances) continue;
+
+      code_.SetValue("FIELD_NAME", Name(field));
+
+      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);
+
+        code_.SetValue(
+            "U_ELEMENT_TYPE",
+            WrapInNameSpace(u->defined_namespace, GetEnumValUse(*u, ev)));
+        code_.SetValue("U_FIELD_TYPE", "const " + full_struct_name + " *");
+        code_.SetValue("U_ELEMENT_NAME", full_struct_name);
+        code_.SetValue("U_FIELD_NAME", Name(field) + "_as_" + Name(ev));
+
+        // `template<> const T *union_name_as<T>() const` accessor.
+        code_ +=
+            "template<> "
+            "inline {{U_FIELD_TYPE}}{{STRUCT_NAME}}::{{FIELD_NAME}}_as"
+            "<{{U_ELEMENT_NAME}}>() const {";
+        code_ += "  return {{U_FIELD_NAME}}();";
+        code_ += "}";
+        code_ += "";
+      }
+    }
+
+    GenBuilders(struct_def);
+
+    if (parser_.opts.generate_object_based_api) {
+      // Generate a pre-declaration for a CreateX method that works with an
+      // unpacked C++ object.
+      code_ += TableCreateSignature(struct_def, true, parser_.opts) + ";";
+      code_ += "";
+    }
+  }
+
+  void GenBuilders(const StructDef &struct_def) {
+    code_.SetValue("STRUCT_NAME", Name(struct_def));
+
+    // Generate a builder struct:
+    code_ += "struct {{STRUCT_NAME}}Builder {";
+    code_ += "  flatbuffers::FlatBufferBuilder &fbb_;";
+    code_ += "  flatbuffers::uoffset_t start_;";
+
+    bool has_string_or_vector_fields = false;
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+      if (!field.deprecated) {
+        const bool is_scalar = IsScalar(field.value.type.base_type);
+        const bool is_string = field.value.type.base_type == BASE_TYPE_STRING;
+        const bool is_vector = field.value.type.base_type == BASE_TYPE_VECTOR;
+        if (is_string || is_vector) { has_string_or_vector_fields = true; }
+
+        std::string offset = GenFieldOffsetName(field);
+        std::string name = GenUnderlyingCast(field, false, Name(field));
+        std::string value = is_scalar ? GenDefaultConstant(field) : "";
+
+        // Generate accessor functions of the form:
+        // void add_name(type name) {
+        //   fbb_.AddElement<type>(offset, name, default);
+        // }
+        code_.SetValue("FIELD_NAME", Name(field));
+        code_.SetValue("FIELD_TYPE", GenTypeWire(field.value.type, " ", true));
+        code_.SetValue("ADD_OFFSET", Name(struct_def) + "::" + offset);
+        code_.SetValue("ADD_NAME", name);
+        code_.SetValue("ADD_VALUE", value);
+        if (is_scalar) {
+          const auto type = GenTypeWire(field.value.type, "", false);
+          code_.SetValue("ADD_FN", "AddElement<" + type + ">");
+        } else if (IsStruct(field.value.type)) {
+          code_.SetValue("ADD_FN", "AddStruct");
+        } else {
+          code_.SetValue("ADD_FN", "AddOffset");
+        }
+
+        code_ += "  void add_{{FIELD_NAME}}({{FIELD_TYPE}}{{FIELD_NAME}}) {";
+        code_ += "    fbb_.{{ADD_FN}}(\\";
+        if (is_scalar) {
+          code_ += "{{ADD_OFFSET}}, {{ADD_NAME}}, {{ADD_VALUE}});";
+        } else {
+          code_ += "{{ADD_OFFSET}}, {{ADD_NAME}});";
+        }
+        code_ += "  }";
+      }
+    }
+
+    // Builder constructor
+    code_ +=
+        "  explicit {{STRUCT_NAME}}Builder(flatbuffers::FlatBufferBuilder "
+        "&_fbb)";
+    code_ += "        : fbb_(_fbb) {";
+    code_ += "    start_ = fbb_.StartTable();";
+    code_ += "  }";
+
+    // Assignment operator;
+    code_ +=
+        "  {{STRUCT_NAME}}Builder &operator="
+        "(const {{STRUCT_NAME}}Builder &);";
+
+    // Finish() function.
+    code_ += "  flatbuffers::Offset<{{STRUCT_NAME}}> Finish() {";
+    code_ += "    const auto end = fbb_.EndTable(start_);";
+    code_ += "    auto o = flatbuffers::Offset<{{STRUCT_NAME}}>(end);";
+
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+      if (!field.deprecated && field.required) {
+        code_.SetValue("FIELD_NAME", Name(field));
+        code_.SetValue("OFFSET_NAME", GenFieldOffsetName(field));
+        code_ += "    fbb_.Required(o, {{STRUCT_NAME}}::{{OFFSET_NAME}});";
+      }
+    }
+    code_ += "    return o;";
+    code_ += "  }";
+    code_ += "};";
+    code_ += "";
+
+    // Generate a convenient CreateX function that uses the above builder
+    // to create a table in one go.
+    code_ +=
+        "inline flatbuffers::Offset<{{STRUCT_NAME}}> "
+        "Create{{STRUCT_NAME}}(";
+    code_ += "    flatbuffers::FlatBufferBuilder &_fbb\\";
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+      if (!field.deprecated) { GenParam(field, false, ",\n    "); }
+    }
+    code_ += ") {";
+
+    code_ += "  {{STRUCT_NAME}}Builder builder_(_fbb);";
+    for (size_t size = struct_def.sortbysize ? sizeof(largest_scalar_t) : 1;
+         size; size /= 2) {
+      for (auto it = struct_def.fields.vec.rbegin();
+           it != struct_def.fields.vec.rend(); ++it) {
+        const auto &field = **it;
+        if (!field.deprecated && (!struct_def.sortbysize ||
+                                  size == SizeOf(field.value.type.base_type))) {
+          code_.SetValue("FIELD_NAME", Name(field));
+          code_ += "  builder_.add_{{FIELD_NAME}}({{FIELD_NAME}});";
+        }
+      }
+    }
+    code_ += "  return builder_.Finish();";
+    code_ += "}";
+    code_ += "";
+
+    // Generate a CreateXDirect function with vector types as parameters
+    if (has_string_or_vector_fields) {
+      code_ +=
+          "inline flatbuffers::Offset<{{STRUCT_NAME}}> "
+          "Create{{STRUCT_NAME}}Direct(";
+      code_ += "    flatbuffers::FlatBufferBuilder &_fbb\\";
+      for (auto it = struct_def.fields.vec.begin();
+           it != struct_def.fields.vec.end(); ++it) {
+        const auto &field = **it;
+        if (!field.deprecated) { GenParam(field, true, ",\n    "); }
+      }
+      // Need to call "Create" with the struct namespace.
+      const auto qualified_create_name =
+          struct_def.defined_namespace->GetFullyQualifiedName("Create");
+      code_.SetValue("CREATE_NAME", TranslateNameSpace(qualified_create_name));
+      code_ += ") {";
+      for (auto it = struct_def.fields.vec.begin();
+           it != struct_def.fields.vec.end(); ++it) {
+        const auto &field = **it;
+        if (!field.deprecated) {
+          code_.SetValue("FIELD_NAME", Name(field));
+          if (field.value.type.base_type == BASE_TYPE_STRING) {
+            if (!field.shared) {
+              code_.SetValue("CREATE_STRING", "CreateString");
+            } else {
+              code_.SetValue("CREATE_STRING", "CreateSharedString");
+            }
+            code_ +=
+                "  auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? "
+                "_fbb.{{CREATE_STRING}}({{FIELD_NAME}}) : 0;";
+          } else if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+            code_ += "  auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? \\";
+            const auto vtype = field.value.type.VectorType();
+            if (IsStruct(vtype)) {
+              const auto type = WrapInNameSpace(*vtype.struct_def);
+              code_ += "_fbb.CreateVectorOfStructs<" + type + ">\\";
+            } else {
+              const auto type = GenTypeWire(vtype, "", false);
+              code_ += "_fbb.CreateVector<" + type + ">\\";
+            }
+            code_ += "(*{{FIELD_NAME}}) : 0;";
+          }
+        }
+      }
+      code_ += "  return {{CREATE_NAME}}{{STRUCT_NAME}}(";
+      code_ += "      _fbb\\";
+      for (auto it = struct_def.fields.vec.begin();
+           it != struct_def.fields.vec.end(); ++it) {
+        const auto &field = **it;
+        if (!field.deprecated) {
+          code_.SetValue("FIELD_NAME", Name(field));
+          code_ += ",\n      {{FIELD_NAME}}\\";
+          if (field.value.type.base_type == BASE_TYPE_STRING ||
+              field.value.type.base_type == BASE_TYPE_VECTOR) {
+            code_ += "__\\";
+          }
+        }
+      }
+      code_ += ");";
+      code_ += "}";
+      code_ += "";
+    }
+  }
+
+  std::string GenUnionUnpackVal(const FieldDef &afield,
+                                const char *vec_elem_access,
+                                const char *vec_type_access) {
+    return afield.value.type.enum_def->name + "Union::UnPack(" + "_e" +
+           vec_elem_access + ", " +
+           EscapeKeyword(afield.name + UnionTypeFieldSuffix()) + "()" +
+           vec_type_access + ", _resolver)";
+  }
+
+  std::string GenUnpackVal(const Type &type, const std::string &val,
+                           bool invector, const FieldDef &afield) {
+    switch (type.base_type) {
+      case BASE_TYPE_STRING: {
+        if (FlexibleStringConstructor(&afield)) {
+          return NativeString(&afield) + "(" + val + "->c_str(), " + val +
+                 "->size())";
+        } else {
+          return val + "->str()";
+        }
+      }
+      case BASE_TYPE_STRUCT: {
+        const auto name = WrapInNameSpace(*type.struct_def);
+        if (IsStruct(type)) {
+          auto native_type = type.struct_def->attributes.Lookup("native_type");
+          if (native_type) {
+            return "flatbuffers::UnPack(*" + val + ")";
+          } else if (invector || afield.native_inline) {
+            return "*" + val;
+          } else {
+            const auto ptype = GenTypeNativePtr(name, &afield, true);
+            return ptype + "(new " + name + "(*" + val + "))";
+          }
+        } else {
+          const auto ptype = GenTypeNativePtr(
+              NativeName(name, type.struct_def, parser_.opts), &afield, true);
+          return ptype + "(" + val + "->UnPack(_resolver))";
+        }
+      }
+      case BASE_TYPE_UNION: {
+        return GenUnionUnpackVal(
+            afield, invector ? "->Get(_i)" : "",
+            invector ? ("->GetEnum<" + type.enum_def->name + ">(_i)").c_str()
+                     : "");
+      }
+      default: {
+        return val;
+        break;
+      }
+    }
+  }
+
+  std::string GenUnpackFieldStatement(const FieldDef &field,
+                                      const FieldDef *union_field) {
+    std::string code;
+    switch (field.value.type.base_type) {
+      case BASE_TYPE_VECTOR: {
+        auto cpp_type = field.attributes.Lookup("cpp_type");
+        std::string indexing;
+        if (field.value.type.enum_def) {
+          indexing += "static_cast<" +
+                      WrapInNameSpace(*field.value.type.enum_def) + ">(";
+        }
+        indexing += "_e->Get(_i)";
+        if (field.value.type.enum_def) { indexing += ")"; }
+        if (field.value.type.element == BASE_TYPE_BOOL) { indexing += " != 0"; }
+
+        // Generate code that pushes data from _e to _o in the form:
+        //   for (uoffset_t i = 0; i < _e->size(); ++i) {
+        //     _o->field.push_back(_e->Get(_i));
+        //   }
+        auto name = Name(field);
+        if (field.value.type.element == BASE_TYPE_UTYPE) {
+          name = StripUnionType(Name(field));
+        }
+        auto access =
+            field.value.type.element == BASE_TYPE_UTYPE
+                ? ".type"
+                : (field.value.type.element == BASE_TYPE_UNION ? ".value" : "");
+        code += "{ _o->" + name + ".resize(_e->size()); ";
+        code += "for (flatbuffers::uoffset_t _i = 0;";
+        code += " _i < _e->size(); _i++) { ";
+        if (cpp_type) {
+          // Generate code that resolves the cpp pointer type, of the form:
+          //  if (resolver)
+          //    (*resolver)(&_o->field, (hash_value_t)(_e));
+          //  else
+          //    _o->field = nullptr;
+          code += "//vector resolver, " + PtrType(&field) + "\n";
+          code += "if (_resolver) ";
+          code += "(*_resolver)";
+          code += "(reinterpret_cast<void **>(&_o->" + name + "[_i]" + access +
+                  "), ";
+          code += "static_cast<flatbuffers::hash_value_t>(" + indexing + "));";
+          if (PtrType(&field) == "naked") {
+            code += " else ";
+            code += "_o->" + name + "[_i]" + access + " = nullptr";
+          } else {
+            // code += " else ";
+            // code += "_o->" + name + "[_i]" + access + " = " +
+            // GenTypeNativePtr(cpp_type->constant, &field, true) + "();";
+            code += "/* else do nothing */";
+          }
+        } else {
+          code += "_o->" + name + "[_i]" + access + " = ";
+          code += GenUnpackVal(field.value.type.VectorType(), indexing, true,
+                               field);
+        }
+        code += "; } }";
+        break;
+      }
+      case BASE_TYPE_UTYPE: {
+        FLATBUFFERS_ASSERT(union_field->value.type.base_type ==
+                           BASE_TYPE_UNION);
+        // Generate code that sets the union type, of the form:
+        //   _o->field.type = _e;
+        code += "_o->" + union_field->name + ".type = _e;";
+        break;
+      }
+      case BASE_TYPE_UNION: {
+        // Generate code that sets the union value, of the form:
+        //   _o->field.value = Union::Unpack(_e, field_type(), resolver);
+        code += "_o->" + Name(field) + ".value = ";
+        code += GenUnionUnpackVal(field, "", "");
+        code += ";";
+        break;
+      }
+      default: {
+        auto cpp_type = field.attributes.Lookup("cpp_type");
+        if (cpp_type) {
+          // Generate code that resolves the cpp pointer type, of the form:
+          //  if (resolver)
+          //    (*resolver)(&_o->field, (hash_value_t)(_e));
+          //  else
+          //    _o->field = nullptr;
+          code += "//scalar resolver, " + PtrType(&field) + " \n";
+          code += "if (_resolver) ";
+          code += "(*_resolver)";
+          code += "(reinterpret_cast<void **>(&_o->" + Name(field) + "), ";
+          code += "static_cast<flatbuffers::hash_value_t>(_e));";
+          if (PtrType(&field) == "naked") {
+            code += " else ";
+            code += "_o->" + Name(field) + " = nullptr;";
+          } else {
+            // code += " else ";
+            // code += "_o->" + Name(field) + " = " +
+            // GenTypeNativePtr(cpp_type->constant, &field, true) + "();";
+            code += "/* else do nothing */;";
+          }
+        } else {
+          // Generate code for assigning the value, of the form:
+          //  _o->field = value;
+          code += "_o->" + Name(field) + " = ";
+          code += GenUnpackVal(field.value.type, "_e", false, field) + ";";
+        }
+        break;
+      }
+    }
+    return code;
+  }
+
+  std::string GenCreateParam(const FieldDef &field) {
+    const IDLOptions &opts = parser_.opts;
+
+    std::string value = "_o->";
+    if (field.value.type.base_type == BASE_TYPE_UTYPE) {
+      value += StripUnionType(Name(field));
+      value += ".type";
+    } else {
+      value += Name(field);
+    }
+    if (field.value.type.base_type != BASE_TYPE_VECTOR &&
+        field.attributes.Lookup("cpp_type")) {
+      auto type = GenTypeBasic(field.value.type, false);
+      value =
+          "_rehasher ? "
+          "static_cast<" +
+          type + ">((*_rehasher)(" + value + GenPtrGet(field) + ")) : 0";
+    }
+
+    std::string code;
+    switch (field.value.type.base_type) {
+      // String fields are of the form:
+      //   _fbb.CreateString(_o->field)
+      // or
+      //   _fbb.CreateSharedString(_o->field)
+      case BASE_TYPE_STRING: {
+        if (!field.shared) {
+          code += "_fbb.CreateString(";
+        } else {
+          code += "_fbb.CreateSharedString(";
+        }
+        code += value;
+        code.push_back(')');
+
+        // For optional fields, check to see if there actually is any data
+        // in _o->field before attempting to access it. If there isn't,
+        // depending on set_empty_to_null either set it to 0 or an empty string.
+        if (!field.required) {
+          auto empty_value =
+              opts.set_empty_to_null ? "0" : "_fbb.CreateSharedString(\"\")";
+          code = value + ".empty() ? " + empty_value + " : " + code;
+        }
+        break;
+      }
+      // Vector fields come in several flavours, of the forms:
+      //   _fbb.CreateVector(_o->field);
+      //   _fbb.CreateVector((const utype*)_o->field.data(), _o->field.size());
+      //   _fbb.CreateVectorOfStrings(_o->field)
+      //   _fbb.CreateVectorOfStructs(_o->field)
+      //   _fbb.CreateVector<Offset<T>>(_o->field.size() [&](size_t i) {
+      //     return CreateT(_fbb, _o->Get(i), rehasher);
+      //   });
+      case BASE_TYPE_VECTOR: {
+        auto vector_type = field.value.type.VectorType();
+        switch (vector_type.base_type) {
+          case BASE_TYPE_STRING: {
+            if (NativeString(&field) == "std::string") {
+              code += "_fbb.CreateVectorOfStrings(" + value + ")";
+            } else {
+              // Use by-function serialization to emulate
+              // CreateVectorOfStrings(); this works also with non-std strings.
+              code +=
+                  "_fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>"
+                  " ";
+              code += "(" + value + ".size(), ";
+              code += "[](size_t i, _VectorArgs *__va) { ";
+              code +=
+                  "return __va->__fbb->CreateString(__va->_" + value + "[i]);";
+              code += " }, &_va )";
+            }
+            break;
+          }
+          case BASE_TYPE_STRUCT: {
+            if (IsStruct(vector_type)) {
+              auto native_type =
+                  field.value.type.struct_def->attributes.Lookup("native_type");
+              if (native_type) {
+                code += "_fbb.CreateVectorOfNativeStructs<";
+                code += WrapInNameSpace(*vector_type.struct_def) + ">";
+              } else {
+                code += "_fbb.CreateVectorOfStructs";
+              }
+              code += "(" + value + ")";
+            } else {
+              code += "_fbb.CreateVector<flatbuffers::Offset<";
+              code += WrapInNameSpace(*vector_type.struct_def) + ">> ";
+              code += "(" + value + ".size(), ";
+              code += "[](size_t i, _VectorArgs *__va) { ";
+              code += "return Create" + vector_type.struct_def->name;
+              code += "(*__va->__fbb, __va->_" + value + "[i]" +
+                      GenPtrGet(field) + ", ";
+              code += "__va->__rehasher); }, &_va )";
+            }
+            break;
+          }
+          case BASE_TYPE_BOOL: {
+            code += "_fbb.CreateVector(" + value + ")";
+            break;
+          }
+          case BASE_TYPE_UNION: {
+            code +=
+                "_fbb.CreateVector<flatbuffers::"
+                "Offset<void>>(" +
+                value +
+                ".size(), [](size_t i, _VectorArgs *__va) { "
+                "return __va->_" +
+                value + "[i].Pack(*__va->__fbb, __va->__rehasher); }, &_va)";
+            break;
+          }
+          case BASE_TYPE_UTYPE: {
+            value = StripUnionType(value);
+            code += "_fbb.CreateVector<uint8_t>(" + value +
+                    ".size(), [](size_t i, _VectorArgs *__va) { "
+                    "return static_cast<uint8_t>(__va->_" +
+                    value + "[i].type); }, &_va)";
+            break;
+          }
+          default: {
+            if (field.value.type.enum_def) {
+              // For enumerations, we need to get access to the array data for
+              // the underlying storage type (eg. uint8_t).
+              const auto basetype = GenTypeBasic(
+                  field.value.type.enum_def->underlying_type, false);
+              code += "_fbb.CreateVectorScalarCast<" + basetype +
+                      ">(flatbuffers::data(" + value + "), " + value +
+                      ".size())";
+            } else if (field.attributes.Lookup("cpp_type")) {
+              auto type = GenTypeBasic(vector_type, false);
+              code += "_fbb.CreateVector<" + type + ">(" + value + ".size(), ";
+              code += "[](size_t i, _VectorArgs *__va) { ";
+              code += "return __va->__rehasher ? ";
+              code += "static_cast<" + type + ">((*__va->__rehasher)";
+              code += "(__va->_" + value + "[i]" + GenPtrGet(field) + ")) : 0";
+              code += "; }, &_va )";
+            } else {
+              code += "_fbb.CreateVector(" + value + ")";
+            }
+            break;
+          }
+        }
+
+        // If set_empty_to_null option is enabled, for optional fields, check to
+        // see if there actually is any data in _o->field before attempting to
+        // access it.
+        if (opts.set_empty_to_null && !field.required) {
+          code = value + ".size() ? " + code + " : 0";
+        }
+        break;
+      }
+      case BASE_TYPE_UNION: {
+        // _o->field.Pack(_fbb);
+        code += value + ".Pack(_fbb)";
+        break;
+      }
+      case BASE_TYPE_STRUCT: {
+        if (IsStruct(field.value.type)) {
+          auto native_type =
+              field.value.type.struct_def->attributes.Lookup("native_type");
+          if (native_type) {
+            code += "flatbuffers::Pack(" + value + ")";
+          } else if (field.native_inline) {
+            code += "&" + value;
+          } else {
+            code += value + " ? " + value + GenPtrGet(field) + " : 0";
+          }
+        } else {
+          // _o->field ? CreateT(_fbb, _o->field.get(), _rehasher);
+          const auto type = field.value.type.struct_def->name;
+          code += value + " ? Create" + type;
+          code += "(_fbb, " + value + GenPtrGet(field) + ", _rehasher)";
+          code += " : 0";
+        }
+        break;
+      }
+      default: {
+        code += value;
+        break;
+      }
+    }
+    return code;
+  }
+
+  // Generate code for tables that needs to come after the regular definition.
+  void GenTablePost(const StructDef &struct_def) {
+    code_.SetValue("STRUCT_NAME", Name(struct_def));
+    code_.SetValue("NATIVE_NAME",
+                   NativeName(Name(struct_def), &struct_def, parser_.opts));
+
+    if (parser_.opts.generate_object_based_api) {
+      // Generate the X::UnPack() method.
+      code_ += "inline " +
+               TableUnPackSignature(struct_def, false, parser_.opts) + " {";
+      code_ += "  auto _o = new {{NATIVE_NAME}}();";
+      code_ += "  UnPackTo(_o, _resolver);";
+      code_ += "  return _o;";
+      code_ += "}";
+      code_ += "";
+
+      code_ += "inline " +
+               TableUnPackToSignature(struct_def, false, parser_.opts) + " {";
+      code_ += "  (void)_o;";
+      code_ += "  (void)_resolver;";
+
+      for (auto it = struct_def.fields.vec.begin();
+           it != struct_def.fields.vec.end(); ++it) {
+        const auto &field = **it;
+        if (field.deprecated) { continue; }
+
+        // Assign a value from |this| to |_o|.   Values from |this| are stored
+        // in a variable |_e| by calling this->field_type().  The value is then
+        // assigned to |_o| using the GenUnpackFieldStatement.
+        const bool is_union = field.value.type.base_type == BASE_TYPE_UTYPE;
+        const auto statement =
+            GenUnpackFieldStatement(field, is_union ? *(it + 1) : nullptr);
+
+        code_.SetValue("FIELD_NAME", Name(field));
+        auto prefix = "  { auto _e = {{FIELD_NAME}}(); ";
+        auto check = IsScalar(field.value.type.base_type) ? "" : "if (_e) ";
+        auto postfix = " };";
+        code_ += std::string(prefix) + check + statement + postfix;
+      }
+      code_ += "}";
+      code_ += "";
+
+      // Generate the X::Pack member function that simply calls the global
+      // CreateX function.
+      code_ += "inline " + TablePackSignature(struct_def, false, parser_.opts) +
+               " {";
+      code_ += "  return Create{{STRUCT_NAME}}(_fbb, _o, _rehasher);";
+      code_ += "}";
+      code_ += "";
+
+      // Generate a CreateX method that works with an unpacked C++ object.
+      code_ += "inline " +
+               TableCreateSignature(struct_def, false, parser_.opts) + " {";
+      code_ += "  (void)_rehasher;";
+      code_ += "  (void)_o;";
+
+      code_ +=
+          "  struct _VectorArgs "
+          "{ flatbuffers::FlatBufferBuilder *__fbb; "
+          "const " +
+          NativeName(Name(struct_def), &struct_def, parser_.opts) +
+          "* __o; "
+          "const flatbuffers::rehasher_function_t *__rehasher; } _va = { "
+          "&_fbb, _o, _rehasher}; (void)_va;";
+
+      for (auto it = struct_def.fields.vec.begin();
+           it != struct_def.fields.vec.end(); ++it) {
+        auto &field = **it;
+        if (field.deprecated) { continue; }
+        code_ += "  auto _" + Name(field) + " = " + GenCreateParam(field) + ";";
+      }
+      // Need to call "Create" with the struct namespace.
+      const auto qualified_create_name =
+          struct_def.defined_namespace->GetFullyQualifiedName("Create");
+      code_.SetValue("CREATE_NAME", TranslateNameSpace(qualified_create_name));
+
+      code_ += "  return {{CREATE_NAME}}{{STRUCT_NAME}}(";
+      code_ += "      _fbb\\";
+      for (auto it = struct_def.fields.vec.begin();
+           it != struct_def.fields.vec.end(); ++it) {
+        auto &field = **it;
+        if (field.deprecated) { continue; }
+
+        bool pass_by_address = false;
+        if (field.value.type.base_type == BASE_TYPE_STRUCT) {
+          if (IsStruct(field.value.type)) {
+            auto native_type =
+                field.value.type.struct_def->attributes.Lookup("native_type");
+            if (native_type) { pass_by_address = true; }
+          }
+        }
+
+        // Call the CreateX function using values from |_o|.
+        if (pass_by_address) {
+          code_ += ",\n      &_" + Name(field) + "\\";
+        } else {
+          code_ += ",\n      _" + Name(field) + "\\";
+        }
+      }
+      code_ += ");";
+      code_ += "}";
+      code_ += "";
+    }
+  }
+
+  static void GenPadding(
+      const FieldDef &field, std::string *code_ptr, int *id,
+      const std::function<void(int bits, std::string *code_ptr, int *id)> &f) {
+    if (field.padding) {
+      for (int i = 0; i < 4; i++) {
+        if (static_cast<int>(field.padding) & (1 << i)) {
+          f((1 << i) * 8, code_ptr, id);
+        }
+      }
+      FLATBUFFERS_ASSERT(!(field.padding & ~0xF));
+    }
+  }
+
+  static void PaddingDefinition(int bits, std::string *code_ptr, int *id) {
+    *code_ptr += "  int" + NumToString(bits) + "_t padding" +
+                 NumToString((*id)++) + "__;";
+  }
+
+  static void PaddingInitializer(int bits, std::string *code_ptr, int *id) {
+    (void)bits;
+    if (*code_ptr != "") *code_ptr += ",\n        ";
+    *code_ptr += "padding" + NumToString((*id)++) + "__(0)";
+  }
+
+  static void PaddingNoop(int bits, std::string *code_ptr, int *id) {
+    (void)bits;
+    *code_ptr += "    (void)padding" + NumToString((*id)++) + "__;";
+  }
+
+  // Generate an accessor struct with constructor for a flatbuffers struct.
+  void GenStruct(const StructDef &struct_def) {
+    // Generate an accessor struct, with private variables of the form:
+    // type name_;
+    // Generates manual padding and alignment.
+    // Variables are private because they contain little endian data on all
+    // platforms.
+    GenComment(struct_def.doc_comment);
+    code_.SetValue("ALIGN", NumToString(struct_def.minalign));
+    code_.SetValue("STRUCT_NAME", Name(struct_def));
+
+    code_ +=
+        "FLATBUFFERS_MANUALLY_ALIGNED_STRUCT({{ALIGN}}) "
+        "{{STRUCT_NAME}} FLATBUFFERS_FINAL_CLASS {";
+    code_ += " private:";
+
+    int padding_id = 0;
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+      const auto &field_type = field.value.type;
+      code_.SetValue("FIELD_TYPE", GenTypeGet(field_type, " ", "", " ", false));
+      code_.SetValue("FIELD_NAME", Name(field));
+      code_.SetValue("ARRAY",
+                     IsArray(field_type)
+                         ? "[" + NumToString(field_type.fixed_length) + "]"
+                         : "");
+      code_ += ("  {{FIELD_TYPE}}{{FIELD_NAME}}_{{ARRAY}};");
+
+      if (field.padding) {
+        std::string padding;
+        GenPadding(field, &padding, &padding_id, PaddingDefinition);
+        code_ += padding;
+      }
+    }
+
+    // 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.
+    code_ += "  {{STRUCT_NAME}}() {";
+    code_ +=
+        "    memset(static_cast<void *>(this), 0, sizeof({{STRUCT_NAME}}));";
+    code_ += "  }";
+
+    // Generate a constructor that takes all fields as arguments,
+    // excluding arrays
+    std::string arg_list;
+    std::string init_list;
+    padding_id = 0;
+    auto first = struct_def.fields.vec.begin();
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+      if (IsArray(field.value.type)) {
+        first++;
+        continue;
+      }
+      const auto member_name = Name(field) + "_";
+      const auto arg_name = "_" + Name(field);
+      const auto arg_type =
+          GenTypeGet(field.value.type, " ", "const ", " &", true);
+
+      if (it != first) { arg_list += ", "; }
+      arg_list += arg_type;
+      arg_list += arg_name;
+      if (!IsArray(field.value.type)) {
+        if (it != first && init_list != "") { init_list += ",\n        "; }
+        init_list += member_name;
+        if (IsScalar(field.value.type.base_type)) {
+          auto type = GenUnderlyingCast(field, false, arg_name);
+          init_list += "(flatbuffers::EndianScalar(" + type + "))";
+        } else {
+          init_list += "(" + arg_name + ")";
+        }
+      }
+      if (field.padding) {
+        GenPadding(field, &init_list, &padding_id, PaddingInitializer);
+      }
+    }
+
+    if (!arg_list.empty()) {
+      code_.SetValue("ARG_LIST", arg_list);
+      code_.SetValue("INIT_LIST", init_list);
+      if (!init_list.empty()) {
+        code_ += "  {{STRUCT_NAME}}({{ARG_LIST}})";
+        code_ += "      : {{INIT_LIST}} {";
+      } else {
+        code_ += "  {{STRUCT_NAME}}({{ARG_LIST}}) {";
+      }
+      padding_id = 0;
+      for (auto it = struct_def.fields.vec.begin();
+           it != struct_def.fields.vec.end(); ++it) {
+        const auto &field = **it;
+        if (IsArray(field.value.type)) {
+          const auto &member = Name(field) + "_";
+          code_ +=
+              "    std::memset(" + member + ", 0, sizeof(" + member + "));";
+        }
+        if (field.padding) {
+          std::string padding;
+          GenPadding(field, &padding, &padding_id, PaddingNoop);
+          code_ += padding;
+        }
+      }
+      code_ += "  }";
+    }
+
+    // Generate accessor methods of the form:
+    // type name() const { return flatbuffers::EndianScalar(name_); }
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+
+      auto field_type = GenTypeGet(field.value.type, " ",
+                                   IsArray(field.value.type) ? "" : "const ",
+                                   IsArray(field.value.type) ? "" : " &", true);
+      auto is_scalar = IsScalar(field.value.type.base_type);
+      auto member = Name(field) + "_";
+      auto value =
+          is_scalar ? "flatbuffers::EndianScalar(" + member + ")" : member;
+
+      code_.SetValue("FIELD_NAME", Name(field));
+      code_.SetValue("FIELD_TYPE", field_type);
+      code_.SetValue("FIELD_VALUE", GenUnderlyingCast(field, true, value));
+
+      GenComment(field.doc_comment, "  ");
+
+      // Generate a const accessor function.
+      if (IsArray(field.value.type)) {
+        auto underlying = GenTypeGet(field.value.type, "", "", "", false);
+        code_ += "  const flatbuffers::Array<" + field_type + ", " +
+                 NumToString(field.value.type.fixed_length) + "> *" +
+                 "{{FIELD_NAME}}() const {";
+        code_ += "    return reinterpret_cast<const flatbuffers::Array<" +
+                 field_type + ", " +
+                 NumToString(field.value.type.fixed_length) +
+                 "> *>({{FIELD_VALUE}});";
+        code_ += "  }";
+      } else {
+        code_ += "  {{FIELD_TYPE}}{{FIELD_NAME}}() const {";
+        code_ += "    return {{FIELD_VALUE}};";
+        code_ += "  }";
+      }
+
+      // Generate a mutable accessor function.
+      if (parser_.opts.mutable_buffer) {
+        auto mut_field_type =
+            GenTypeGet(field.value.type, " ", "",
+                       IsArray(field.value.type) ? "" : " &", true);
+        code_.SetValue("FIELD_TYPE", mut_field_type);
+        if (is_scalar) {
+          code_.SetValue("ARG", GenTypeBasic(field.value.type, true));
+          code_.SetValue("FIELD_VALUE",
+                         GenUnderlyingCast(field, false, "_" + Name(field)));
+
+          code_ += "  void mutate_{{FIELD_NAME}}({{ARG}} _{{FIELD_NAME}}) {";
+          code_ +=
+              "    flatbuffers::WriteScalar(&{{FIELD_NAME}}_, "
+              "{{FIELD_VALUE}});";
+          code_ += "  }";
+        } else if (IsArray(field.value.type)) {
+          auto underlying = GenTypeGet(field.value.type, "", "", "", false);
+          code_ += "  flatbuffers::Array<" + mut_field_type + ", " +
+                   NumToString(field.value.type.fixed_length) +
+                   "> *" + "mutable_{{FIELD_NAME}}() {";
+          code_ += "    return reinterpret_cast<flatbuffers::Array<" +
+                   mut_field_type + ", " +
+                   NumToString(field.value.type.fixed_length) +
+                   "> *>({{FIELD_VALUE}});";
+          code_ += "  }";
+        } else {
+          code_ += "  {{FIELD_TYPE}}mutable_{{FIELD_NAME}}() {";
+          code_ += "    return {{FIELD_VALUE}};";
+          code_ += "  }";
+        }
+      }
+
+      // Generate a comparison function for this field if it is a key.
+      if (field.key) { GenKeyFieldMethods(field); }
+    }
+    code_.SetValue("NATIVE_NAME", Name(struct_def));
+    GenOperatorNewDelete(struct_def);
+    code_ += "};";
+
+    code_.SetValue("STRUCT_BYTE_SIZE", NumToString(struct_def.bytesize));
+    code_ += "FLATBUFFERS_STRUCT_END({{STRUCT_NAME}}, {{STRUCT_BYTE_SIZE}});";
+    if (parser_.opts.gen_compare) GenCompareOperator(struct_def, "()");
+    code_ += "";
+  }
+
+  // Set up the correct namespace. Only open a namespace if the existing one is
+  // different (closing/opening only what is necessary).
+  //
+  // The file must start and end with an empty (or null) namespace so that
+  // namespaces are properly opened and closed.
+  void SetNameSpace(const Namespace *ns) {
+    if (cur_name_space_ == ns) { return; }
+
+    // Compute the size of the longest common namespace prefix.
+    // If cur_name_space is A::B::C::D and ns is A::B::E::F::G,
+    // the common prefix is A::B:: and we have old_size = 4, new_size = 5
+    // and common_prefix_size = 2
+    size_t old_size = cur_name_space_ ? cur_name_space_->components.size() : 0;
+    size_t new_size = ns ? ns->components.size() : 0;
+
+    size_t common_prefix_size = 0;
+    while (common_prefix_size < old_size && common_prefix_size < new_size &&
+           ns->components[common_prefix_size] ==
+               cur_name_space_->components[common_prefix_size]) {
+      common_prefix_size++;
+    }
+
+    // Close cur_name_space in reverse order to reach the common prefix.
+    // In the previous example, D then C are closed.
+    for (size_t j = old_size; j > common_prefix_size; --j) {
+      code_ += "}  // namespace " + cur_name_space_->components[j - 1];
+    }
+    if (old_size != common_prefix_size) { code_ += ""; }
+
+    // open namespace parts to reach the ns namespace
+    // in the previous example, E, then F, then G are opened
+    for (auto j = common_prefix_size; j != new_size; ++j) {
+      code_ += "namespace " + ns->components[j] + " {";
+    }
+    if (new_size != common_prefix_size) { code_ += ""; }
+
+    cur_name_space_ = ns;
+  }
+
+  const TypedFloatConstantGenerator float_const_gen_;
+};
+
+}  // namespace cpp
+
+bool GenerateCPP(const Parser &parser, const std::string &path,
+                 const std::string &file_name) {
+  cpp::CppGenerator generator(parser, path, file_name);
+  return generator.generate();
+}
+
+std::string CPPMakeRule(const Parser &parser, const std::string &path,
+                        const std::string &file_name) {
+  const auto filebase =
+      flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
+  const auto included_files = parser.GetIncludedFilesRecursive(file_name);
+  std::string make_rule = GeneratedFileName(path, filebase) + ": ";
+  for (auto it = included_files.begin(); it != included_files.end(); ++it) {
+    make_rule += " " + *it;
+  }
+  return make_rule;
+}
+
+}  // namespace flatbuffers
diff --git a/src/idl_gen_dart.cpp b/src/idl_gen_dart.cpp
new file mode 100644
index 0000000..2346a85
--- /dev/null
+++ b/src/idl_gen_dart.cpp
@@ -0,0 +1,914 @@
+/*
+ * Copyright 2018 Dan Field
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// independent from idl_parser, since this code is not needed for most clients
+#include <cassert>
+
+#include "flatbuffers/code_generators.h"
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+namespace flatbuffers {
+
+static std::string GeneratedFileName(const std::string &path,
+                                     const std::string &file_name) {
+  return path + file_name + "_generated.dart";
+}
+
+namespace dart {
+
+const std::string _kFb = "fb";
+// see https://www.dartlang.org/guides/language/language-tour#keywords
+// yeild*, async*, and sync* shouldn't be problems anyway but keeping them in
+static const char *keywords[] = {
+  "abstract",   "deferred", "if",       "super",   "as",       "do",
+  "implements", "switch",   "assert",   "dynamic", "import",   "sync*",
+  "async",      "else",     "in",       "this",    "async*",   "enum",
+  "is",         "throw",    "await",    "export",  "library",  "true",
+  "break",      "external", "new",      "try",     "case",     "extends",
+  "null",       "typedef",  "catch",    "factory", "operator", "var",
+  "class",      "false",    "part",     "void",    "const",    "final",
+  "rethrow",    "while",    "continue", "finally", "return",   "with",
+  "covariant",  "for",      "set",      "yield",   "default",  "get",
+  "static",     "yield*"
+};
+
+// Iterate through all definitions we haven't generate code for (enums, structs,
+// and tables) and output them to a single file.
+class DartGenerator : public BaseGenerator {
+ public:
+  typedef std::map<std::string, std::string> namespace_code_map;
+
+  DartGenerator(const Parser &parser, const std::string &path,
+                const std::string &file_name)
+      : BaseGenerator(parser, path, file_name, "", ".") {}
+  // Iterate through all definitions we haven't generate code for (enums,
+  // structs, and tables) and output them to a single file.
+  bool generate() {
+    std::string code;
+    namespace_code_map namespace_code;
+    GenerateEnums(&namespace_code);
+    GenerateStructs(&namespace_code);
+
+    for (auto kv = namespace_code.begin(); kv != namespace_code.end(); ++kv) {
+      code.clear();
+      code = code + "// " + FlatBuffersGeneratedWarning() + "\n";
+      code = code +
+             "// ignore_for_file: unused_import, unused_field, "
+             "unused_local_variable\n\n";
+
+      code += "library " + kv->first + ";\n\n";
+
+      code += "import 'dart:typed_data' show Uint8List;\n";
+      code += "import 'package:flat_buffers/flat_buffers.dart' as " + _kFb +
+              ";\n\n";
+
+      if (parser_.opts.include_dependence_headers) {
+        GenIncludeDependencies(&code, kv->first);
+      }
+
+      for (auto kv2 = namespace_code.begin(); kv2 != namespace_code.end();
+           ++kv2) {
+        if (kv2->first != kv->first) {
+          code += "import '" +
+                  GeneratedFileName("./", file_name_ + "_" + kv2->first) +
+                  "' as " + ImportAliasName(kv2->first) + ";\n";
+        }
+      }
+      code += "\n";
+      code += kv->second;
+
+      if (!SaveFile(
+              GeneratedFileName(path_, file_name_ + "_" + kv->first).c_str(),
+              code, false)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+ private:
+  static std::string ImportAliasName(const std::string &ns) {
+    std::string ret;
+    ret.assign(ns);
+    size_t pos = ret.find('.');
+    while (pos != std::string::npos) {
+      ret.replace(pos, 1, "_");
+      pos = ret.find('.', pos + 1);
+    }
+
+    return ret;
+  }
+
+  static std::string BuildNamespaceName(const Namespace &ns) {
+    std::stringstream sstream;
+    std::copy(ns.components.begin(), ns.components.end() - 1,
+              std::ostream_iterator<std::string>(sstream, "."));
+
+    auto ret = sstream.str() + ns.components.back();
+    for (size_t i = 0; i < ret.size(); i++) {
+      auto lower = tolower(ret[i]);
+      if (lower != ret[i]) {
+        ret[i] = static_cast<char>(lower);
+        if (i != 0 && ret[i - 1] != '.') {
+          ret.insert(i, "_");
+          i++;
+        }
+      }
+    }
+    // std::transform(ret.begin(), ret.end(), ret.begin(), ::tolower);
+    return ret;
+  }
+
+  void GenIncludeDependencies(std::string* code, const std::string& the_namespace) {
+    for (auto it = parser_.included_files_.begin();
+         it != parser_.included_files_.end(); ++it) {
+      if (it->second.empty()) continue;
+
+      auto noext = flatbuffers::StripExtension(it->second);
+      auto basename = flatbuffers::StripPath(noext);
+
+      *code += "import '" + GeneratedFileName("", basename + "_" + the_namespace) + "';\n";
+    }
+  }
+
+  static std::string EscapeKeyword(const std::string &name) {
+    for (size_t i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) {
+      if (name == keywords[i]) { return MakeCamel(name + "_", false); }
+    }
+
+    return MakeCamel(name, false);
+  }
+
+  void GenerateEnums(namespace_code_map *namespace_code) {
+    for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
+         ++it) {
+      auto &enum_def = **it;
+      GenEnum(enum_def, namespace_code);  // enum_code_ptr);
+    }
+  }
+
+  void GenerateStructs(namespace_code_map *namespace_code) {
+    for (auto it = parser_.structs_.vec.begin();
+         it != parser_.structs_.vec.end(); ++it) {
+      auto &struct_def = **it;
+      GenStruct(struct_def, namespace_code);
+    }
+  }
+
+  // Generate a documentation comment, if available.
+  static void GenDocComment(const std::vector<std::string> &dc,
+                            std::string *code_ptr,
+                            const std::string &extra_lines,
+                            const char *indent = nullptr) {
+    if (dc.empty() && extra_lines.empty()) {
+      // Don't output empty comment blocks with 0 lines of comment content.
+      return;
+    }
+
+    auto &code = *code_ptr;
+
+    for (auto it = dc.begin(); it != dc.end(); ++it) {
+      if (indent) code += indent;
+      code += "/// " + *it + "\n";
+    }
+    if (!extra_lines.empty()) {
+      if (!dc.empty()) {
+        if (indent) code += indent;
+        code += "///\n";
+      }
+      if (indent) code += indent;
+      std::string::size_type start = 0;
+      for (;;) {
+        auto end = extra_lines.find('\n', start);
+        if (end != std::string::npos) {
+          code += "/// " + extra_lines.substr(start, end - start) + "\n";
+          start = end + 1;
+        } else {
+          code += "/// " + extra_lines.substr(start) + "\n";
+          break;
+        }
+      }
+    }
+  }
+
+  static void GenDocComment(std::string *code_ptr,
+                            const std::string &extra_lines) {
+    GenDocComment(std::vector<std::string>(), code_ptr, extra_lines);
+  }
+
+  // Generate an enum declaration and an enum string lookup table.
+  void GenEnum(EnumDef &enum_def, namespace_code_map *namespace_code) {
+    if (enum_def.generated) return;
+    auto ns = BuildNamespaceName(*enum_def.defined_namespace);
+    std::string code;
+    GenDocComment(enum_def.doc_comment, &code, "");
+
+    auto name = enum_def.is_union ? enum_def.name + "TypeId" : enum_def.name;
+    auto is_bit_flags = enum_def.attributes.Lookup("bit_flags");
+
+    code += "class " + name + " {\n";
+    code += "  final int value;\n";
+    code += "  const " + name + "._(this.value);\n\n";
+    code += "  factory " + name + ".fromValue(int value) {\n";
+    code += "    if (value == null) value = 0;\n";
+
+    code += "    if (!values.containsKey(value)) {\n";
+    code +=
+        "      throw new StateError('Invalid value $value for bit flag enum ";
+    code += name + "');\n";
+    code += "    }\n";
+
+    code += "    return values[value];\n";
+    code += "  }\n\n";
+
+    // this is meaningless for bit_flags
+    // however, note that unlike "regular" dart enums this enum can still have
+    // holes.
+    if (!is_bit_flags) {
+      code += "  static const int minValue = " +
+              enum_def.ToString(*enum_def.MinValue()) + ";\n";
+      code += "  static const int maxValue = " +
+              enum_def.ToString(*enum_def.MaxValue()) + ";\n";
+    }
+
+    code +=
+        "  static bool containsValue(int value) =>"
+        " values.containsKey(value);\n\n";
+
+    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().begin()) { code += '\n'; }
+        GenDocComment(ev.doc_comment, &code, "", "  ");
+      }
+      code += "  static const " + name + " " + ev.name + " = ";
+      code += "const " + name + "._(" + enum_def.ToString(ev) + ");\n";
+    }
+
+    code += "  static get values => {";
+    for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
+      auto &ev = **it;
+      code += enum_def.ToString(ev) + ": " + ev.name + ",";
+    }
+    code += "};\n\n";
+
+    code += "  static const " + _kFb + ".Reader<" + name +
+            "> reader = const _" + name + "Reader();\n\n";
+    code += "  @override\n";
+    code += "  String toString() {\n";
+    code += "    return '" + name + "{value: $value}';\n";
+    code += "  }\n";
+    code += "}\n\n";
+
+    GenEnumReader(enum_def, name, &code);
+    (*namespace_code)[ns] += code;
+  }
+
+  void GenEnumReader(EnumDef &enum_def, const std::string &name,
+                     std::string *code_ptr) {
+    auto &code = *code_ptr;
+
+    code += "class _" + name + "Reader extends " + _kFb + ".Reader<" + name +
+            "> {\n";
+    code += "  const _" + name + "Reader();\n\n";
+    code += "  @override\n";
+    code += "  int get size => 1;\n\n";
+    code += "  @override\n";
+    code +=
+        "  " + name + " read(" + _kFb + ".BufferContext bc, int offset) =>\n";
+    code += "      new " + name + ".fromValue(const " + _kFb + "." +
+            GenType(enum_def.underlying_type) + "Reader().read(bc, offset));\n";
+    code += "}\n\n";
+  }
+
+  static std::string GenType(const Type &type) {
+    switch (type.base_type) {
+      case BASE_TYPE_BOOL: return "Bool";
+      case BASE_TYPE_CHAR: return "Int8";
+      case BASE_TYPE_UTYPE:
+      case BASE_TYPE_UCHAR: return "Uint8";
+      case BASE_TYPE_SHORT: return "Int16";
+      case BASE_TYPE_USHORT: return "Uint16";
+      case BASE_TYPE_INT: return "Int32";
+      case BASE_TYPE_UINT: return "Uint32";
+      case BASE_TYPE_LONG: return "Int64";
+      case BASE_TYPE_ULONG: return "Uint64";
+      case BASE_TYPE_FLOAT: return "Float32";
+      case BASE_TYPE_DOUBLE: return "Float64";
+      case BASE_TYPE_STRING: return "String";
+      case BASE_TYPE_VECTOR: return GenType(type.VectorType());
+      case BASE_TYPE_STRUCT: return type.struct_def->name;
+      case BASE_TYPE_UNION: return type.enum_def->name + "TypeId";
+      default: return "Table";
+    }
+  }
+
+  std::string GenReaderTypeName(const Type &type, Namespace *current_namespace,
+                                const FieldDef &def,
+                                bool parent_is_vector = false) {
+    if (type.base_type == BASE_TYPE_BOOL) {
+      return "const " + _kFb + ".BoolReader()";
+    } else if (type.base_type == BASE_TYPE_VECTOR) {
+      return "const " + _kFb + ".ListReader<" +
+             GenDartTypeName(type.VectorType(), current_namespace, def) + ">(" +
+             GenReaderTypeName(type.VectorType(), current_namespace, def,
+                               true) +
+             ")";
+    } else if (type.base_type == BASE_TYPE_STRING) {
+      return "const " + _kFb + ".StringReader()";
+    }
+    if (IsScalar(type.base_type)) {
+      if (type.enum_def && parent_is_vector) {
+        return GenDartTypeName(type, current_namespace, def) + ".reader";
+      }
+      return "const " + _kFb + "." + GenType(type) + "Reader()";
+    } else {
+      return GenDartTypeName(type, current_namespace, def) + ".reader";
+    }
+  }
+
+  std::string GenDartTypeName(const Type &type, Namespace *current_namespace,
+                              const FieldDef &def, bool addBuilder = false) {
+    if (type.enum_def) {
+      if (type.enum_def->is_union && type.base_type != BASE_TYPE_UNION) {
+        return type.enum_def->name + "TypeId";
+      } else if (type.enum_def->is_union) {
+        return "dynamic";
+      } else if (type.base_type != BASE_TYPE_VECTOR) {
+        return type.enum_def->name;
+      }
+    }
+
+    switch (type.base_type) {
+      case BASE_TYPE_BOOL: return "bool";
+      case BASE_TYPE_LONG:
+      case BASE_TYPE_ULONG:
+      case BASE_TYPE_INT:
+      case BASE_TYPE_UINT:
+      case BASE_TYPE_SHORT:
+      case BASE_TYPE_USHORT:
+      case BASE_TYPE_CHAR:
+      case BASE_TYPE_UCHAR: return "int";
+      case BASE_TYPE_FLOAT:
+      case BASE_TYPE_DOUBLE: return "double";
+      case BASE_TYPE_STRING: return "String";
+      case BASE_TYPE_STRUCT:
+        return MaybeWrapNamespace(
+            type.struct_def->name + (addBuilder ? "ObjectBuilder" : ""),
+            current_namespace, def);
+      case BASE_TYPE_VECTOR:
+        return "List<" +
+               GenDartTypeName(type.VectorType(), current_namespace, def,
+                               addBuilder) +
+               ">";
+      default: assert(0); return "dynamic";
+    }
+  }
+
+  static const std::string MaybeWrapNamespace(const std::string &type_name,
+                                              Namespace *current_ns,
+                                              const FieldDef &field) {
+    auto curr_ns_str = BuildNamespaceName(*current_ns);
+    std::string field_ns_str = "";
+    if (field.value.type.struct_def) {
+      field_ns_str +=
+          BuildNamespaceName(*field.value.type.struct_def->defined_namespace);
+    } else if (field.value.type.enum_def) {
+      field_ns_str +=
+          BuildNamespaceName(*field.value.type.enum_def->defined_namespace);
+    }
+
+    if (field_ns_str != "" && field_ns_str != curr_ns_str) {
+      return ImportAliasName(field_ns_str) + "." + type_name;
+    } else {
+      return type_name;
+    }
+  }
+
+  // Generate an accessor struct with constructor for a flatbuffers struct.
+  void GenStruct(const StructDef &struct_def,
+                 namespace_code_map *namespace_code) {
+    if (struct_def.generated) return;
+
+    auto object_namespace = BuildNamespaceName(*struct_def.defined_namespace);
+    std::string code;
+
+    const auto &object_name = struct_def.name;
+
+    // Emit constructor
+
+    GenDocComment(struct_def.doc_comment, &code, "");
+
+    auto reader_name = "_" + object_name + "Reader";
+    auto builder_name = object_name + "Builder";
+    auto object_builder_name = object_name + "ObjectBuilder";
+
+    std::string reader_code, builder_code;
+
+    code += "class " + object_name + " {\n";
+
+    code += "  " + object_name + "._(this._bc, this._bcOffset);\n";
+    if (!struct_def.fixed) {
+      code += "  factory " + object_name + "(List<int> bytes) {\n";
+      code += "    " + _kFb + ".BufferContext rootRef = new " + _kFb +
+              ".BufferContext.fromBytes(bytes);\n";
+      code += "    return reader.read(rootRef, 0);\n";
+      code += "  }\n";
+    }
+
+    code += "\n";
+    code += "  static const " + _kFb + ".Reader<" + object_name +
+            "> reader = const " + reader_name + "();\n\n";
+
+    code += "  final " + _kFb + ".BufferContext _bc;\n";
+    code += "  final int _bcOffset;\n\n";
+
+    GenImplementationGetters(struct_def, &code);
+
+    code += "}\n\n";
+
+    GenReader(struct_def, &reader_name, &reader_code);
+    GenBuilder(struct_def, &builder_name, &builder_code);
+    GenObjectBuilder(struct_def, &object_builder_name, &builder_code);
+
+    code += reader_code;
+    code += builder_code;
+
+    (*namespace_code)[object_namespace] += code;
+  }
+
+  std::string NamespaceAliasFromUnionType(const std::string &in) {
+    if (in.find('_') == std::string::npos) { return in; }
+
+    std::stringstream ss(in);
+    std::string item;
+    std::vector<std::string> parts;
+    std::string ns;
+
+    while (std::getline(ss, item, '_')) { parts.push_back(item); }
+
+    for (auto it = parts.begin(); it != parts.end() - 1; ++it) {
+      auto &part = *it;
+
+      for (size_t i = 0; i < part.length(); i++) {
+        if (i && !isdigit(part[i]) &&
+            part[i] == static_cast<char>(toupper(part[i]))) {
+          ns += "_";
+          ns += static_cast<char>(tolower(part[i]));
+        } else {
+          ns += static_cast<char>(tolower(part[i]));
+        }
+      }
+      if (it != parts.end() - 2) { ns += "_"; }
+    }
+
+    return ns + "." + parts.back();
+  }
+
+  void GenImplementationGetters(const StructDef &struct_def,
+                                std::string *code_ptr) {
+    auto &code = *code_ptr;
+
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+
+      std::string field_name = MakeCamel(field.name, false);
+      std::string type_name = GenDartTypeName(
+          field.value.type, struct_def.defined_namespace, field, false);
+
+      GenDocComment(field.doc_comment, &code, "", "  ");
+
+      code += "  " + type_name + " get " + field_name;
+      if (field.value.type.base_type == BASE_TYPE_UNION) {
+        code += " {\n";
+        code += "    switch (" + field_name + "Type?.value) {\n";
+        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);
+          code += "      case " + enum_def.ToString(ev) + ": return " +
+                  enum_name + ".reader.vTableGet(_bc, _bcOffset, " +
+                  NumToString(field.value.offset) + ", null);\n";
+        }
+        code += "      default: return null;\n";
+        code += "    }\n";
+        code += "  }\n";
+      } else {
+        code += " => ";
+        if (field.value.type.enum_def &&
+            field.value.type.base_type != BASE_TYPE_VECTOR) {
+          code += "new " +
+                  GenDartTypeName(field.value.type,
+                                  struct_def.defined_namespace, field) +
+                  ".fromValue(";
+        }
+
+        code += GenReaderTypeName(field.value.type,
+                                  struct_def.defined_namespace, field);
+        if (struct_def.fixed) {
+          code +=
+              ".read(_bc, _bcOffset + " + NumToString(field.value.offset) + ")";
+        } else {
+          code += ".vTableGet(_bc, _bcOffset, " +
+                  NumToString(field.value.offset) + ", ";
+          if (!field.value.constant.empty() && field.value.constant != "0") {
+            if (IsBool(field.value.type.base_type)) {
+              code += "true";
+            } else {
+              code += field.value.constant;
+            }
+          } else {
+            if (IsBool(field.value.type.base_type)) {
+              code += "false";
+            } else if (IsScalar(field.value.type.base_type)) {
+              code += "0";
+            } else {
+              code += "null";
+            }
+          }
+          code += ")";
+        }
+        if (field.value.type.enum_def &&
+            field.value.type.base_type != BASE_TYPE_VECTOR) {
+          code += ")";
+        }
+        code += ";\n";
+      }
+    }
+
+    code += "\n";
+
+    code += "  @override\n";
+    code += "  String toString() {\n";
+    code += "    return '" + struct_def.name + "{";
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+      code +=
+          MakeCamel(field.name, false) + ": $" + MakeCamel(field.name, false);
+      if (it != struct_def.fields.vec.end() - 1) { code += ", "; }
+    }
+    code += "}';\n";
+    code += "  }\n";
+  }
+
+  void GenReader(const StructDef &struct_def, std::string *reader_name_ptr,
+                 std::string *code_ptr) {
+    auto &code = *code_ptr;
+    auto &reader_name = *reader_name_ptr;
+    auto &impl_name = struct_def.name;
+
+    code += "class " + reader_name + " extends " + _kFb;
+    if (struct_def.fixed) {
+      code += ".StructReader<";
+    } else {
+      code += ".TableReader<";
+    }
+    code += impl_name + "> {\n";
+    code += "  const " + reader_name + "();\n\n";
+
+    if (struct_def.fixed) {
+      code += "  @override\n";
+      code += "  int get size => " + NumToString(struct_def.bytesize) + ";\n\n";
+    }
+    code += "  @override\n";
+    code += "  " + impl_name +
+            " createObject(fb.BufferContext bc, int offset) => \n    new " +
+            impl_name + "._(bc, offset);\n";
+    code += "}\n\n";
+  }
+
+  void GenBuilder(const StructDef &struct_def, std::string *builder_name_ptr,
+                  std::string *code_ptr) {
+    if (struct_def.fields.vec.size() == 0) { return; }
+    auto &code = *code_ptr;
+    auto &builder_name = *builder_name_ptr;
+
+    code += "class " + builder_name + " {\n";
+    code += "  " + builder_name + "(this.fbBuilder) {\n";
+    code += "    assert(fbBuilder != null);\n";
+    code += "  }\n\n";
+    code += "  final " + _kFb + ".Builder fbBuilder;\n\n";
+
+    if (struct_def.fixed) {
+      StructBuilderBody(struct_def, code_ptr);
+    } else {
+      TableBuilderBody(struct_def, code_ptr);
+    }
+
+    code += "}\n\n";
+  }
+
+  void StructBuilderBody(const StructDef &struct_def, std::string *code_ptr) {
+    auto &code = *code_ptr;
+
+    code += "  int finish(";
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+
+      if (IsStruct(field.value.type)) {
+        code += "fb.StructBuilder";
+      } else {
+        code += GenDartTypeName(field.value.type, struct_def.defined_namespace,
+                                field);
+      }
+      code += " " + field.name;
+      if (it != struct_def.fields.vec.end() - 1) { code += ", "; }
+    }
+    code += ") {\n";
+
+    for (auto it = struct_def.fields.vec.rbegin();
+         it != struct_def.fields.vec.rend(); ++it) {
+      auto &field = **it;
+
+      if (field.deprecated) continue;
+
+      if (field.padding) {
+        code += "    fbBuilder.pad(" + NumToString(field.padding) + ");\n";
+      }
+
+      if (IsStruct(field.value.type)) {
+        code += "    " + field.name + "();\n";
+      } else {
+        code += "    fbBuilder.put" + GenType(field.value.type) + "(";
+        code += field.name;
+        if (field.value.type.enum_def) { code += "?.value"; }
+        code += ");\n";
+      }
+    }
+    code += "    return fbBuilder.offset;\n";
+    code += "  }\n\n";
+  }
+
+  void TableBuilderBody(const StructDef &struct_def, std::string *code_ptr) {
+    auto &code = *code_ptr;
+
+    code += "  void begin() {\n";
+    code += "    fbBuilder.startTable();\n";
+    code += "  }\n\n";
+
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+
+      auto offset = it - struct_def.fields.vec.begin();
+
+      if (IsScalar(field.value.type.base_type)) {
+        code += "  int add" + MakeCamel(field.name) + "(";
+        code += GenDartTypeName(field.value.type, struct_def.defined_namespace,
+                                field);
+        code += " " + MakeCamel(field.name, false) + ") {\n";
+        code += "    fbBuilder.add" + GenType(field.value.type) + "(" +
+                NumToString(offset) + ", ";
+        code += MakeCamel(field.name, false);
+        if (field.value.type.enum_def) { code += "?.value"; }
+        code += ");\n";
+      } else if (IsStruct(field.value.type)) {
+        code += "  int add" + MakeCamel(field.name) + "(int offset) {\n";
+        code +=
+            "    fbBuilder.addStruct(" + NumToString(offset) + ", offset);\n";
+      } else {
+        code += "  int add" + MakeCamel(field.name) + "Offset(int offset) {\n";
+        code +=
+            "    fbBuilder.addOffset(" + NumToString(offset) + ", offset);\n";
+      }
+      code += "    return fbBuilder.offset;\n";
+      code += "  }\n";
+    }
+
+    code += "\n";
+    code += "  int finish() {\n";
+    code += "    return fbBuilder.endTable();\n";
+    code += "  }\n";
+  }
+
+  void GenObjectBuilder(const StructDef &struct_def,
+                        std::string *builder_name_ptr, std::string *code_ptr) {
+    auto &code = *code_ptr;
+    auto &builder_name = *builder_name_ptr;
+
+    code += "class " + builder_name + " extends " + _kFb + ".ObjectBuilder {\n";
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+      code += "  final " +
+              GenDartTypeName(field.value.type, struct_def.defined_namespace,
+                              field, true) +
+              " _" + MakeCamel(field.name, false) + ";\n";
+    }
+    code += "\n";
+    code += "  " + builder_name + "(";
+    if (struct_def.fields.vec.size() != 0) {
+      code +=
+
+          "{\n";
+      for (auto it = struct_def.fields.vec.begin();
+           it != struct_def.fields.vec.end(); ++it) {
+        auto &field = **it;
+        if (field.deprecated) continue;
+        code += "    " +
+                GenDartTypeName(field.value.type, struct_def.defined_namespace,
+                                field, true) +
+                " " + MakeCamel(field.name, false) + ",\n";
+      }
+      code += "  })\n";
+      code += "      : ";
+      for (auto it = struct_def.fields.vec.begin();
+           it != struct_def.fields.vec.end(); ++it) {
+        auto &field = **it;
+        if (field.deprecated) continue;
+        code += "_" + MakeCamel(field.name, false) + " = " +
+                MakeCamel(field.name, false);
+        if (it == struct_def.fields.vec.end() - 1) {
+          code += ";\n\n";
+        } else {
+          code += ",\n        ";
+        }
+      }
+    } else {
+      code += ");\n\n";
+    }
+
+    code += "  /// Finish building, and store into the [fbBuilder].\n";
+    code += "  @override\n";
+    code += "  int finish(\n";
+    code += "    " + _kFb + ".Builder fbBuilder) {\n";
+    code += "    assert(fbBuilder != null);\n";
+
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+      if (IsScalar(field.value.type.base_type) || IsStruct(field.value.type))
+        continue;
+
+      code += "    final int " + MakeCamel(field.name, false) + "Offset";
+      if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+        code +=
+            " = _" + MakeCamel(field.name, false) + "?.isNotEmpty == true\n";
+        code += "        ? fbBuilder.writeList";
+        switch (field.value.type.VectorType().base_type) {
+          case BASE_TYPE_STRING:
+            code += "(_" + MakeCamel(field.name, false) +
+                    ".map((b) => fbBuilder.writeString(b)).toList())";
+            break;
+          case BASE_TYPE_STRUCT:
+            if (field.value.type.struct_def->fixed) {
+              code += "OfStructs(_" + MakeCamel(field.name, false) + ")";
+            } else {
+              code += "(_" + MakeCamel(field.name, false) +
+                      ".map((b) => b.getOrCreateOffset(fbBuilder)).toList())";
+            }
+            break;
+          default:
+            code += GenType(field.value.type.VectorType()) + "(_" +
+                    MakeCamel(field.name, false);
+            if (field.value.type.enum_def) { code += ".map((f) => f.value)"; }
+            code += ")";
+        }
+        code += "\n        : null;\n";
+      } else if (field.value.type.base_type == BASE_TYPE_STRING) {
+        code += " = fbBuilder.writeString(_" + MakeCamel(field.name, false) + ");\n";
+      } else {
+        code += " = _" + MakeCamel(field.name, false) +
+                "?.getOrCreateOffset(fbBuilder);\n";
+      }
+    }
+
+    code += "\n";
+    if (struct_def.fixed) {
+      StructObjectBuilderBody(struct_def, code_ptr);
+    } else {
+      TableObjectBuilderBody(struct_def, code_ptr);
+    }
+    code += "  }\n\n";
+
+    code += "  /// Convenience method to serialize to byte list.\n";
+    code += "  @override\n";
+    code += "  Uint8List toBytes([String fileIdentifier]) {\n";
+    code += "    " + _kFb + ".Builder fbBuilder = new ";
+    code += _kFb + ".Builder();\n";
+    code += "    int offset = finish(fbBuilder);\n";
+    code += "    return fbBuilder.finish(offset, fileIdentifier);\n";
+    code += "  }\n";
+    code += "}\n";
+  }
+
+  void StructObjectBuilderBody(const StructDef &struct_def,
+                               std::string *code_ptr,
+                               bool prependUnderscore = true) {
+    auto &code = *code_ptr;
+
+    for (auto it = struct_def.fields.vec.rbegin();
+         it != struct_def.fields.vec.rend(); ++it) {
+      auto &field = **it;
+
+      if (field.deprecated) continue;
+
+      if (field.padding) {
+        code += "    fbBuilder.pad(" + NumToString(field.padding) + ");\n";
+      }
+
+      if (IsStruct(field.value.type)) {
+        code += "    ";
+        if (prependUnderscore) { code += "_"; }
+        code += field.name + ".finish(fbBuilder);\n";
+      } else {
+        code += "    fbBuilder.put" + GenType(field.value.type) + "(";
+        if (prependUnderscore) { code += "_"; }
+        code += field.name;
+        if (field.value.type.enum_def) { code += "?.value"; }
+        code += ");\n";
+      }
+    }
+
+    code += "    return fbBuilder.offset;\n";
+  }
+
+  void TableObjectBuilderBody(const StructDef &struct_def,
+                              std::string *code_ptr,
+                              bool prependUnderscore = true) {
+    std::string &code = *code_ptr;
+    code += "    fbBuilder.startTable();\n";
+
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+
+      if (field.deprecated) continue;
+
+      auto offset = it - struct_def.fields.vec.begin();
+      if (IsScalar(field.value.type.base_type)) {
+        code += "    fbBuilder.add" + GenType(field.value.type) + "(" +
+                NumToString(offset) + ", ";
+        if (prependUnderscore) { code += "_"; }
+        code += MakeCamel(field.name, false);
+        if (field.value.type.enum_def) { code += "?.value"; }
+        code += ");\n";
+      } else if (IsStruct(field.value.type)) {
+        code += "    if (";
+        if (prependUnderscore) { code += "_"; }
+        code += MakeCamel(field.name, false) + " != null) {\n";
+        code += "      fbBuilder.addStruct(" + NumToString(offset) + ", ";
+        code += "_" + MakeCamel(field.name, false) + ".finish(fbBuilder));\n";
+        code += "    }\n";
+      } else {
+        code +=
+            "    if (" + MakeCamel(field.name, false) + "Offset != null) {\n";
+        code += "      fbBuilder.addOffset(" + NumToString(offset) + ", " +
+                MakeCamel(field.name, false) + "Offset);\n";
+        code += "    }\n";
+      }
+    }
+    code += "    return fbBuilder.endTable();\n";
+  }
+};
+}  // namespace dart
+
+bool GenerateDart(const Parser &parser, const std::string &path,
+                  const std::string &file_name) {
+  dart::DartGenerator generator(parser, path, file_name);
+  return generator.generate();
+}
+
+std::string DartMakeRule(const Parser &parser, const std::string &path,
+                         const std::string &file_name) {
+  assert(parser.opts.lang <= IDLOptions::kMAX);
+
+  auto filebase =
+      flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
+  auto make_rule = GeneratedFileName(path, filebase) + ": ";
+
+  auto included_files = parser.GetIncludedFilesRecursive(file_name);
+  for (auto it = included_files.begin(); it != included_files.end(); ++it) {
+    make_rule += " " + *it;
+  }
+  return make_rule;
+}
+
+}  // namespace flatbuffers
diff --git a/src/idl_gen_fbs.cpp b/src/idl_gen_fbs.cpp
new file mode 100644
index 0000000..e5f3723
--- /dev/null
+++ b/src/idl_gen_fbs.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// independent from idl_parser, since this code is not needed for most clients
+
+#include "flatbuffers/code_generators.h"
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+namespace flatbuffers {
+
+static std::string GenType(const Type &type, bool underlying = false) {
+  switch (type.base_type) {
+    case BASE_TYPE_STRUCT:
+      return type.struct_def->defined_namespace->GetFullyQualifiedName(
+          type.struct_def->name);
+    case BASE_TYPE_VECTOR: return "[" + GenType(type.VectorType()) + "]";
+    default:
+      if (type.enum_def && !underlying) {
+        return type.enum_def->defined_namespace->GetFullyQualifiedName(
+            type.enum_def->name);
+      } else {
+        return kTypeNames[type.base_type];
+      }
+  }
+}
+
+static void GenNameSpace(const Namespace &name_space, std::string *_schema,
+                         const Namespace **last_namespace) {
+  if (*last_namespace == &name_space) return;
+  *last_namespace = &name_space;
+  auto &schema = *_schema;
+  schema += "namespace ";
+  for (auto it = name_space.components.begin();
+       it != name_space.components.end(); ++it) {
+    if (it != name_space.components.begin()) schema += ".";
+    schema += *it;
+  }
+  schema += ";\n\n";
+}
+
+// Generate a flatbuffer schema from the Parser's internal representation.
+std::string GenerateFBS(const Parser &parser, const std::string &file_name) {
+  // Proto namespaces may clash with table names, escape the ones that were
+  // generated from a table:
+  for (auto it = parser.namespaces_.begin(); it != parser.namespaces_.end();
+       ++it) {
+    auto &ns = **it;
+    for (size_t i = 0; i < ns.from_table; i++) {
+      ns.components[ns.components.size() - 1 - i] += "_";
+    }
+  }
+
+  std::string schema;
+  schema += "// Generated from " + file_name + ".proto\n\n";
+  if (parser.opts.include_dependence_headers) {
+    // clang-format off
+    #ifdef FBS_GEN_INCLUDES  // TODO: currently all in one file.
+    int num_includes = 0;
+    for (auto it = parser.included_files_.begin();
+         it != parser.included_files_.end(); ++it) {
+      if (it->second.empty())
+        continue;
+      auto basename = flatbuffers::StripPath(
+                        flatbuffers::StripExtension(it->second));
+      schema += "include \"" + basename + ".fbs\";\n";
+      num_includes++;
+    }
+    if (num_includes) schema += "\n";
+    #endif
+    // clang-format on
+  }
+  // Generate code for all the enum declarations.
+  const Namespace *last_namespace = nullptr;
+  for (auto enum_def_it = parser.enums_.vec.begin();
+       enum_def_it != parser.enums_.vec.end(); ++enum_def_it) {
+    EnumDef &enum_def = **enum_def_it;
+    GenNameSpace(*enum_def.defined_namespace, &schema, &last_namespace);
+    GenComment(enum_def.doc_comment, &schema, nullptr);
+    if (enum_def.is_union)
+      schema += "union " + enum_def.name;
+    else
+      schema += "enum " + enum_def.name + " : ";
+    schema += GenType(enum_def.underlying_type, true) + " {\n";
+    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)
+        schema += "  " + GenType(ev.union_type) + ",\n";
+      else
+        schema += "  " + ev.name + " = " + enum_def.ToString(ev) + ",\n";
+    }
+    schema += "}\n\n";
+  }
+  // Generate code for all structs/tables.
+  for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end();
+       ++it) {
+    StructDef &struct_def = **it;
+    GenNameSpace(*struct_def.defined_namespace, &schema, &last_namespace);
+    GenComment(struct_def.doc_comment, &schema, nullptr);
+    schema += "table " + struct_def.name + " {\n";
+    for (auto field_it = struct_def.fields.vec.begin();
+         field_it != struct_def.fields.vec.end(); ++field_it) {
+      auto &field = **field_it;
+      if (field.value.type.base_type != BASE_TYPE_UTYPE) {
+        GenComment(field.doc_comment, &schema, nullptr, "  ");
+        schema += "  " + field.name + ":" + GenType(field.value.type);
+        if (field.value.constant != "0") schema += " = " + field.value.constant;
+        if (field.required) schema += " (required)";
+        schema += ";\n";
+      }
+    }
+    schema += "}\n\n";
+  }
+  return schema;
+}
+
+bool GenerateFBS(const Parser &parser, const std::string &path,
+                 const std::string &file_name) {
+  return SaveFile((path + file_name + ".fbs").c_str(),
+                  GenerateFBS(parser, file_name), false);
+}
+
+}  // namespace flatbuffers
diff --git a/src/idl_gen_general.cpp b/src/idl_gen_general.cpp
new file mode 100644
index 0000000..8dca792
--- /dev/null
+++ b/src/idl_gen_general.cpp
@@ -0,0 +1,1667 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// independent from idl_parser, since this code is not needed for most clients
+
+#include "flatbuffers/code_generators.h"
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+#if defined(FLATBUFFERS_CPP98_STL)
+#  include <cctype>
+#endif  // defined(FLATBUFFERS_CPP98_STL)
+
+namespace flatbuffers {
+
+// These arrays need to correspond to the IDLOptions::k enum.
+
+struct LanguageParameters {
+  IDLOptions::Language language;
+  // Whether function names in the language typically start with uppercase.
+  bool first_camel_upper;
+  std::string file_extension;
+  std::string string_type;
+  std::string bool_type;
+  std::string open_curly;
+  std::string accessor_type;
+  std::string const_decl;
+  std::string unsubclassable_decl;
+  std::string enum_decl;
+  std::string enum_separator;
+  std::string getter_prefix;
+  std::string getter_suffix;
+  std::string inheritance_marker;
+  std::string namespace_ident;
+  std::string namespace_begin;
+  std::string namespace_end;
+  std::string set_bb_byteorder;
+  std::string get_bb_position;
+  std::string get_fbb_offset;
+  std::string accessor_prefix;
+  std::string accessor_prefix_static;
+  std::string optional_suffix;
+  std::string includes;
+  std::string class_annotation;
+  std::string generated_type_annotation;
+  CommentConfig comment_config;
+  const FloatConstantGenerator *float_gen;
+};
+
+const LanguageParameters &GetLangParams(IDLOptions::Language lang) {
+  static TypedFloatConstantGenerator CSharpFloatGen(
+      "Double.", "Single.", "NaN", "PositiveInfinity", "NegativeInfinity");
+
+  static TypedFloatConstantGenerator JavaFloatGen(
+      "Double.", "Float.", "NaN", "POSITIVE_INFINITY", "NEGATIVE_INFINITY");
+
+  static const LanguageParameters language_parameters[] = {
+    {
+        IDLOptions::kJava,
+        false,
+        ".java",
+        "String",
+        "boolean ",
+        " {\n",
+        "class ",
+        " final ",
+        "final ",
+        "final class ",
+        ";\n",
+        "()",
+        "",
+        " extends ",
+        "package ",
+        ";",
+        "",
+        "_bb.order(ByteOrder.LITTLE_ENDIAN); ",
+        "position()",
+        "offset()",
+        "",
+        "",
+        "",
+        "import java.nio.*;\nimport java.lang.*;\nimport "
+        "java.util.*;\nimport com.google.flatbuffers.*;\n",
+        "\n@SuppressWarnings(\"unused\")\n",
+        "\n@javax.annotation.Generated(value=\"flatc\")\n",
+        {
+            "/**",
+            " *",
+            " */",
+        },
+        &JavaFloatGen
+    },
+    {
+        IDLOptions::kCSharp,
+        true,
+        ".cs",
+        "string",
+        "bool ",
+        "\n{\n",
+        "struct ",
+        " readonly ",
+        "",
+        "enum ",
+        ",\n",
+        " { get",
+        "} ",
+        " : ",
+        "namespace ",
+        "\n{",
+        "\n}\n",
+        "",
+        "Position",
+        "Offset",
+        "__p.",
+        "Table.",
+        "?",
+        "using global::System;\nusing global::FlatBuffers;\n\n",
+        "",
+        "",
+        {
+            nullptr,
+            "///",
+            nullptr,
+        },
+        &CSharpFloatGen
+    },
+  };
+
+  if (lang == IDLOptions::kJava) {
+    return language_parameters[0];
+  } else {
+    FLATBUFFERS_ASSERT(lang == IDLOptions::kCSharp);
+    return language_parameters[1];
+  }
+}
+
+namespace general {
+class GeneralGenerator : public BaseGenerator {
+ public:
+  GeneralGenerator(const Parser &parser, const std::string &path,
+                   const std::string &file_name)
+      : BaseGenerator(parser, path, file_name, "", "."),
+        lang_(GetLangParams(parser_.opts.lang)),
+        cur_name_space_(nullptr) {}
+
+  GeneralGenerator &operator=(const GeneralGenerator &);
+  bool generate() {
+    std::string one_file_code;
+    cur_name_space_ = parser_.current_namespace_;
+
+    for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
+         ++it) {
+      std::string enumcode;
+      auto &enum_def = **it;
+      if (!parser_.opts.one_file) cur_name_space_ = enum_def.defined_namespace;
+      GenEnum(enum_def, &enumcode);
+      if (parser_.opts.one_file) {
+        one_file_code += enumcode;
+      } else {
+        if (!SaveType(enum_def.name, *enum_def.defined_namespace, enumcode,
+                      false))
+          return false;
+      }
+    }
+
+    for (auto it = parser_.structs_.vec.begin();
+         it != parser_.structs_.vec.end(); ++it) {
+      std::string declcode;
+      auto &struct_def = **it;
+      if (!parser_.opts.one_file)
+        cur_name_space_ = struct_def.defined_namespace;
+      GenStruct(struct_def, &declcode);
+      if (parser_.opts.one_file) {
+        one_file_code += declcode;
+      } else {
+        if (!SaveType(struct_def.name, *struct_def.defined_namespace, declcode,
+                      true))
+          return false;
+      }
+    }
+
+    if (parser_.opts.one_file) {
+      return SaveType(file_name_, *parser_.current_namespace_, one_file_code,
+                      true);
+    }
+    return true;
+  }
+
+  // Save out the generated code for a single class while adding
+  // declaration boilerplate.
+  bool SaveType(const std::string &defname, const Namespace &ns,
+                const std::string &classcode, bool needs_includes) const {
+    if (!classcode.length()) return true;
+
+    std::string code;
+    if (lang_.language == IDLOptions::kCSharp) {
+      code =
+          "// <auto-generated>\n"
+          "//  " +
+          std::string(FlatBuffersGeneratedWarning()) +
+          "\n"
+          "// </auto-generated>\n\n";
+    } else {
+      code = "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n";
+    }
+
+    std::string namespace_name = FullNamespace(".", ns);
+    if (!namespace_name.empty()) {
+      code += lang_.namespace_ident + namespace_name + lang_.namespace_begin;
+      code += "\n\n";
+    }
+    if (needs_includes) {
+      code += lang_.includes;
+      if (parser_.opts.gen_nullable) {
+        code += "\nimport javax.annotation.Nullable;\n";
+      }
+      code += lang_.class_annotation;
+    }
+    if (parser_.opts.gen_generated) {
+      code += lang_.generated_type_annotation;
+    }
+    code += classcode;
+    if (!namespace_name.empty()) code += lang_.namespace_end;
+    auto filename = NamespaceDir(ns) + defname + lang_.file_extension;
+    return SaveFile(filename.c_str(), code, false);
+  }
+
+  const Namespace *CurrentNameSpace() const { return cur_name_space_; }
+
+  std::string FunctionStart(char upper) const {
+    return std::string() + (lang_.language == IDLOptions::kJava
+                                ? static_cast<char>(tolower(upper))
+                                : upper);
+  }
+
+  std::string GenNullableAnnotation(const Type &t) const {
+    return lang_.language == IDLOptions::kJava && parser_.opts.gen_nullable &&
+                   !IsScalar(DestinationType(t, true).base_type)
+               ? " @Nullable "
+               : "";
+  }
+
+  std::string GenTypeBasic(const Type &type, bool enableLangOverrides) const {
+    // clang-format off
+  static const char * const java_typename[] = {
+    #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+        CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
+        #JTYPE,
+      FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+    #undef FLATBUFFERS_TD
+  };
+
+  static const char * const csharp_typename[] = {
+    #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+        CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
+        #NTYPE,
+      FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+    #undef FLATBUFFERS_TD
+  };
+    // clang-format on
+
+    if (enableLangOverrides) {
+      if (lang_.language == IDLOptions::kCSharp) {
+        if (IsEnum(type)) return WrapInNameSpace(*type.enum_def);
+        if (type.base_type == BASE_TYPE_STRUCT) {
+          return "Offset<" + WrapInNameSpace(*type.struct_def) + ">";
+        }
+      }
+    }
+
+    if (lang_.language == IDLOptions::kJava) {
+      return java_typename[type.base_type];
+    } else {
+      FLATBUFFERS_ASSERT(lang_.language == IDLOptions::kCSharp);
+      return csharp_typename[type.base_type];
+    }
+  }
+
+  std::string GenTypeBasic(const Type &type) const {
+    return GenTypeBasic(type, true);
+  }
+
+  std::string GenTypePointer(const Type &type) const {
+    switch (type.base_type) {
+      case BASE_TYPE_STRING: return lang_.string_type;
+      case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType());
+      case BASE_TYPE_STRUCT: return WrapInNameSpace(*type.struct_def);
+      case BASE_TYPE_UNION:
+        // Unions in C# use a generic Table-derived type for better type safety
+        if (lang_.language == IDLOptions::kCSharp) return "TTable";
+        FLATBUFFERS_FALLTHROUGH();  // else fall thru
+      default: return "Table";
+    }
+  }
+
+  std::string GenTypeGet(const Type &type) const {
+    return IsScalar(type.base_type)
+               ? GenTypeBasic(type)
+               : (IsArray(type) ? GenTypeGet(type.VectorType())
+                                : GenTypePointer(type));
+  }
+
+  // Find the destination type the user wants to receive the value in (e.g.
+  // one size higher signed types for unsigned serialized values in Java).
+  Type DestinationType(const Type &type, bool vectorelem) const {
+    if (lang_.language != IDLOptions::kJava) return type;
+    switch (type.base_type) {
+      // We use int for both uchar/ushort, since that generally means less
+      // casting than using short for uchar.
+      case BASE_TYPE_UCHAR: return Type(BASE_TYPE_INT);
+      case BASE_TYPE_USHORT: return Type(BASE_TYPE_INT);
+      case BASE_TYPE_UINT: return Type(BASE_TYPE_LONG);
+      case BASE_TYPE_ARRAY:
+      case BASE_TYPE_VECTOR:
+        if (vectorelem) return DestinationType(type.VectorType(), vectorelem);
+        FLATBUFFERS_FALLTHROUGH(); // else fall thru
+      default: return type;
+    }
+  }
+
+  std::string GenOffsetType(const StructDef &struct_def) const {
+    if (lang_.language == IDLOptions::kCSharp) {
+      return "Offset<" + WrapInNameSpace(struct_def) + ">";
+    } else {
+      return "int";
+    }
+  }
+
+  std::string GenOffsetConstruct(const StructDef &struct_def,
+                                 const std::string &variable_name) const {
+    if (lang_.language == IDLOptions::kCSharp) {
+      return "new Offset<" + WrapInNameSpace(struct_def) + ">(" +
+             variable_name + ")";
+    }
+    return variable_name;
+  }
+
+  std::string GenVectorOffsetType() const {
+    if (lang_.language == IDLOptions::kCSharp) {
+      return "VectorOffset";
+    } else {
+      return "int";
+    }
+  }
+
+  // Generate destination type name
+  std::string GenTypeNameDest(const Type &type) const {
+    return GenTypeGet(DestinationType(type, true));
+  }
+
+  // Mask to turn serialized value into destination type value.
+  std::string DestinationMask(const Type &type, bool vectorelem) const {
+    if (lang_.language != IDLOptions::kJava) return "";
+    switch (type.base_type) {
+      case BASE_TYPE_UCHAR: return " & 0xFF";
+      case BASE_TYPE_USHORT: return " & 0xFFFF";
+      case BASE_TYPE_UINT: return " & 0xFFFFFFFFL";
+      case BASE_TYPE_VECTOR:
+        if (vectorelem) return DestinationMask(type.VectorType(), vectorelem);
+        FLATBUFFERS_FALLTHROUGH(); // else fall thru
+      default: return "";
+    }
+  }
+
+  // Casts necessary to correctly read serialized data
+  std::string DestinationCast(const Type &type) const {
+    if (IsSeries(type)) {
+      return DestinationCast(type.VectorType());
+    } else {
+      switch (lang_.language) {
+        case IDLOptions::kJava:
+          // Cast necessary to correctly read serialized unsigned values.
+          if (type.base_type == BASE_TYPE_UINT) return "(long)";
+          break;
+
+        case IDLOptions::kCSharp:
+          // Cast from raw integral types to enum.
+          if (IsEnum(type)) return "(" + WrapInNameSpace(*type.enum_def) + ")";
+          break;
+
+        default: break;
+      }
+    }
+    return "";
+  }
+
+  // Cast statements for mutator method parameters.
+  // In Java, parameters representing unsigned numbers need to be cast down to
+  // their respective type. For example, a long holding an unsigned int value
+  // would be cast down to int before being put onto the buffer. In C#, one cast
+  // directly cast an Enum to its underlying type, which is essential before
+  // putting it onto the buffer.
+  std::string SourceCast(const Type &type, bool castFromDest) const {
+    if (IsSeries(type)) {
+      return SourceCast(type.VectorType(), castFromDest);
+    } else {
+      switch (lang_.language) {
+        case IDLOptions::kJava:
+          if (castFromDest) {
+            if (type.base_type == BASE_TYPE_UINT)
+              return "(int)";
+            else if (type.base_type == BASE_TYPE_USHORT)
+              return "(short)";
+            else if (type.base_type == BASE_TYPE_UCHAR)
+              return "(byte)";
+          }
+          break;
+        case IDLOptions::kCSharp:
+          if (IsEnum(type)) return "(" + GenTypeBasic(type, false) + ")";
+          break;
+        default: break;
+      }
+    }
+    return "";
+  }
+
+  std::string SourceCast(const Type &type) const { return SourceCast(type, true); }
+
+  std::string SourceCastBasic(const Type &type, bool castFromDest) const {
+    return IsScalar(type.base_type) ? SourceCast(type, castFromDest) : "";
+  }
+
+  std::string SourceCastBasic(const Type &type) const {
+    return SourceCastBasic(type, true);
+  }
+
+  std::string GenEnumDefaultValue(const FieldDef &field) const {
+    auto &value = field.value;
+    FLATBUFFERS_ASSERT(value.type.enum_def);
+    auto &enum_def = *value.type.enum_def;
+    auto enum_val = enum_def.FindByValue(value.constant);
+    return enum_val ? (WrapInNameSpace(enum_def) + "." + enum_val->name)
+                    : value.constant;
+  }
+
+  std::string GenDefaultValue(const FieldDef &field, bool enableLangOverrides) const {
+    auto& value = field.value;
+    if (enableLangOverrides) {
+      // handles both enum case and vector of enum case
+      if (lang_.language == IDLOptions::kCSharp &&
+          value.type.enum_def != nullptr &&
+          value.type.base_type != BASE_TYPE_UNION) {
+        return GenEnumDefaultValue(field);
+      }
+    }
+
+    auto longSuffix = lang_.language == IDLOptions::kJava ? "L" : "";
+    switch (value.type.base_type) {
+      case BASE_TYPE_BOOL: return value.constant == "0" ? "false" : "true";
+      case BASE_TYPE_ULONG: {
+        if (lang_.language != IDLOptions::kJava) return value.constant;
+        // Converts the ulong into its bits signed equivalent
+        uint64_t defaultValue = StringToUInt(value.constant.c_str());
+        return NumToString(static_cast<int64_t>(defaultValue)) + longSuffix;
+      }
+      case BASE_TYPE_UINT:
+      case BASE_TYPE_LONG: return value.constant + longSuffix;
+      default:
+        if(IsFloat(value.type.base_type))
+          return lang_.float_gen->GenFloatConstant(field);
+        else
+          return value.constant;
+    }
+  }
+
+  std::string GenDefaultValue(const FieldDef &field) const {
+    return GenDefaultValue(field, true);
+  }
+
+  std::string GenDefaultValueBasic(const FieldDef &field,
+                                   bool enableLangOverrides) const {
+    auto& value = field.value;
+    if (!IsScalar(value.type.base_type)) {
+      if (enableLangOverrides) {
+        if (lang_.language == IDLOptions::kCSharp) {
+          switch (value.type.base_type) {
+            case BASE_TYPE_STRING: return "default(StringOffset)";
+            case BASE_TYPE_STRUCT:
+              return "default(Offset<" +
+                     WrapInNameSpace(*value.type.struct_def) + ">)";
+            case BASE_TYPE_VECTOR: return "default(VectorOffset)";
+            default: break;
+          }
+        }
+      }
+      return "0";
+    }
+    return GenDefaultValue(field, enableLangOverrides);
+  }
+
+  std::string GenDefaultValueBasic(const FieldDef &field) const {
+    return GenDefaultValueBasic(field, true);
+  }
+
+  void GenEnum(EnumDef &enum_def, std::string *code_ptr) const {
+    std::string &code = *code_ptr;
+    if (enum_def.generated) return;
+
+    // Generate enum definitions of the form:
+    // public static (final) int name = value;
+    // In Java, we use ints rather than the Enum feature, because we want them
+    // to map directly to how they're used in C/C++ and file formats.
+    // That, and Java Enums are expensive, and not universally liked.
+    GenComment(enum_def.doc_comment, code_ptr, &lang_.comment_config);
+
+    // In C# this indicates enumeration values can be treated as bit flags.
+    if (lang_.language == IDLOptions::kCSharp && enum_def.attributes.Lookup("bit_flags")) {
+      code += "[System.FlagsAttribute]\n";
+    }
+    if (enum_def.attributes.Lookup("private")) {
+      // For Java, we leave the enum unmarked to indicate package-private
+      // For C# we mark the enum as internal
+      if (lang_.language == IDLOptions::kCSharp) {
+        code += "internal ";
+      }
+    } else {
+      code += "public ";
+    }
+    code += lang_.enum_decl + enum_def.name;
+    if (lang_.language == IDLOptions::kCSharp) {
+      code += lang_.inheritance_marker +
+              GenTypeBasic(enum_def.underlying_type, false);
+    }
+    code += lang_.open_curly;
+    if (lang_.language == IDLOptions::kJava) {
+      code += "  private " + enum_def.name + "() { }\n";
+    }
+    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) {
+        code += "  public static";
+        code += lang_.const_decl;
+        code += GenTypeBasic(enum_def.underlying_type, false);
+      }
+      code += (lang_.language == IDLOptions::kJava) ? " " : "  ";
+      code += ev.name + " = ";
+      code += enum_def.ToString(ev);
+      code += lang_.enum_separator;
+    }
+
+    // Generate a generate string table for enum values.
+    // We do not do that for C# where this functionality is native.
+    if (lang_.language != IDLOptions::kCSharp) {
+      // Problem is, if values are very sparse that could generate really big
+      // tables. Ideally in that case we generate a map lookup instead, but for
+      // the moment we simply don't output a table at all.
+      auto range = enum_def.Distance();
+      // Average distance between values above which we consider a table
+      // "too sparse". Change at will.
+      static const uint64_t kMaxSparseness = 5;
+      if (range / static_cast<uint64_t>(enum_def.size()) < kMaxSparseness) {
+        code += "\n  public static";
+        code += lang_.const_decl;
+        code += lang_.string_type;
+        code += "[] names = { ";
+        auto val = enum_def.Vals().front();
+        for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
+             ++it) {
+          auto ev = *it;
+          for (auto k = enum_def.Distance(val, ev); k > 1; --k)
+            code += "\"\", ";
+          val = ev;
+          code += "\"" + (*it)->name + "\", ";
+        }
+        code += "};\n\n";
+        code += "  public static ";
+        code += lang_.string_type;
+        code += " " + MakeCamel("name", lang_.first_camel_upper);
+        code += "(int e) { return names[e";
+        if (enum_def.MinValue()->IsNonZero())
+          code += " - " + enum_def.MinValue()->name;
+        code += "]; }\n";
+      }
+    }
+
+    // Close the class
+    code += "}";
+    // Java does not need the closing semi-colon on class definitions.
+    code += (lang_.language != IDLOptions::kJava) ? ";" : "";
+    code += "\n\n";
+  }
+
+  // Returns the function name that is able to read a value of the given type.
+  std::string GenGetter(const Type &type) const {
+    switch (type.base_type) {
+      case BASE_TYPE_STRING: return lang_.accessor_prefix + "__string";
+      case BASE_TYPE_STRUCT: return lang_.accessor_prefix + "__struct";
+      case BASE_TYPE_UNION: return lang_.accessor_prefix + "__union";
+      case BASE_TYPE_VECTOR: return GenGetter(type.VectorType());
+      case BASE_TYPE_ARRAY: return GenGetter(type.VectorType());
+      default: {
+        std::string getter =
+            lang_.accessor_prefix + "bb." + FunctionStart('G') + "et";
+        if (type.base_type == BASE_TYPE_BOOL) {
+          getter = "0!=" + getter;
+        } else if (GenTypeBasic(type, false) != "byte") {
+          getter += MakeCamel(GenTypeBasic(type, false));
+        }
+        return getter;
+      }
+    }
+  }
+
+  // Returns the function name that is able to read a value of the given type.
+  std::string GenGetterForLookupByKey(flatbuffers::FieldDef *key_field,
+                                      const std::string &data_buffer,
+                                      const char *num = nullptr) const {
+    auto type = key_field->value.type;
+    auto dest_mask = DestinationMask(type, true);
+    auto dest_cast = DestinationCast(type);
+    auto getter = data_buffer + "." + FunctionStart('G') + "et";
+    if (GenTypeBasic(type, false) != "byte") {
+      getter += MakeCamel(GenTypeBasic(type, false));
+    }
+    getter = dest_cast + getter + "(" + GenOffsetGetter(key_field, num) + ")" +
+             dest_mask;
+    return getter;
+  }
+
+  // Direct mutation is only allowed for scalar fields.
+  // Hence a setter method will only be generated for such fields.
+  std::string GenSetter(const Type &type) const {
+    if (IsScalar(type.base_type)) {
+      std::string setter =
+          lang_.accessor_prefix + "bb." + FunctionStart('P') + "ut";
+      if (GenTypeBasic(type, false) != "byte" &&
+          type.base_type != BASE_TYPE_BOOL) {
+        setter += MakeCamel(GenTypeBasic(type, false));
+      }
+      return setter;
+    } else {
+      return "";
+    }
+  }
+
+  // Returns the method name for use with add/put calls.
+  std::string GenMethod(const Type &type) const {
+    return IsScalar(type.base_type) ? MakeCamel(GenTypeBasic(type, false))
+                                    : (IsStruct(type) ? "Struct" : "Offset");
+  }
+
+  // Recursively generate arguments for a constructor, to deal with nested
+  // structs.
+  void GenStructArgs(const StructDef &struct_def, std::string *code_ptr,
+                     const char *nameprefix, size_t array_count = 0) const {
+    std::string &code = *code_ptr;
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      const auto &field_type = field.value.type;
+      const auto array_field = IsArray(field_type);
+      const auto &type = array_field ? field_type.VectorType()
+                                     : DestinationType(field_type, false);
+      const auto array_cnt = array_field ? (array_count + 1) : array_count;
+      if (IsStruct(type)) {
+        // Generate arguments for a struct inside a struct. To ensure names
+        // don't clash, and to make it obvious these arguments are constructing
+        // a nested struct, prefix the name with the field name.
+        GenStructArgs(*field_type.struct_def, code_ptr,
+                      (nameprefix + (field.name + "_")).c_str(), array_cnt);
+      } else {
+        code += ", ";
+        code += GenTypeBasic(type);
+        if (lang_.language == IDLOptions::kJava) {
+          for (size_t i = 0; i < array_cnt; i++) code += "[]";
+        } else if (lang_.language == IDLOptions::kCSharp) {
+          if (array_cnt > 0) {
+            code += "[";
+            for (size_t i = 1; i < array_cnt; i++) code += ",";
+            code += "]";
+          }
+        } else {
+          FLATBUFFERS_ASSERT(0);
+        }
+        code += " ";
+        code += nameprefix;
+        code += MakeCamel(field.name, lang_.first_camel_upper);
+      }
+    }
+  }
+
+  // Recusively generate struct construction statements of the form:
+  // builder.putType(name);
+  // and insert manual padding.
+  void GenStructBody(const StructDef &struct_def, std::string *code_ptr,
+                     const char *nameprefix, size_t index = 0,
+                     bool in_array = false) const {
+    std::string &code = *code_ptr;
+    std::string indent((index + 1) * 2, ' ');
+    code += indent + "  builder." + FunctionStart('P') + "rep(";
+    code += NumToString(struct_def.minalign) + ", ";
+    code += NumToString(struct_def.bytesize) + ");\n";
+    for (auto it = struct_def.fields.vec.rbegin();
+         it != struct_def.fields.vec.rend(); ++it) {
+      auto &field = **it;
+      const auto &field_type = field.value.type;
+      if (field.padding) {
+        code += indent + "  builder." + FunctionStart('P') + "ad(";
+        code += NumToString(field.padding) + ");\n";
+      }
+      if (IsStruct(field_type)) {
+        GenStructBody(*field_type.struct_def, code_ptr,
+                      (nameprefix + (field.name + "_")).c_str(), index,
+                      in_array);
+      } else {
+        const auto &type =
+            IsArray(field_type) ? field_type.VectorType() : field_type;
+        const auto index_var = "_idx" + NumToString(index);
+        if (IsArray(field_type)) {
+          code += indent + "  for (int " + index_var + " = ";
+          code += NumToString(field_type.fixed_length);
+          code += "; " + index_var + " > 0; " + index_var + "--) {\n";
+          in_array = true;
+        }
+        if (IsStruct(type)) {
+          GenStructBody(*field_type.struct_def, code_ptr,
+                        (nameprefix + (field.name + "_")).c_str(), index + 1,
+                        in_array);
+        } else {
+          code += IsArray(field_type) ? "  " : "";
+          code += indent + "  builder." + FunctionStart('P') + "ut";
+          code += GenMethod(type) + "(";
+          code += SourceCast(type);
+          auto argname =
+              nameprefix + MakeCamel(field.name, lang_.first_camel_upper);
+          code += argname;
+          size_t array_cnt = index + (IsArray(field_type) ? 1 : 0);
+          if (lang_.language == IDLOptions::kJava) {
+            for (size_t i = 0; in_array && i < array_cnt; i++) {
+              code += "[_idx" + NumToString(i) + "-1]";
+            }
+          } else if (lang_.language == IDLOptions::kCSharp) {
+            if (array_cnt > 0) {
+              code += "[";
+              for (size_t i = 0; in_array && i < array_cnt; i++) {
+                code += "_idx" + NumToString(i) + "-1";
+                if (i != (array_cnt - 1)) code += ",";
+              }
+              code += "]";
+            }
+          } else {
+            FLATBUFFERS_ASSERT(0);
+          }
+          code += ");\n";
+        }
+        if (IsArray(field_type)) { code += indent + "  }\n"; }
+      }
+    }
+  }
+
+  std::string GenByteBufferLength(const char *bb_name) const {
+    std::string bb_len = bb_name;
+    if (lang_.language == IDLOptions::kCSharp)
+      bb_len += ".Length";
+    else
+      bb_len += ".capacity()";
+    return bb_len;
+  }
+
+  std::string GenOffsetGetter(flatbuffers::FieldDef *key_field,
+                              const char *num = nullptr) const {
+    std::string key_offset = "";
+    key_offset += lang_.accessor_prefix_static + "__offset(" +
+                  NumToString(key_field->value.offset) + ", ";
+    if (num) {
+      key_offset += num;
+      key_offset +=
+          (lang_.language == IDLOptions::kCSharp ? ".Value, builder.DataBuffer)"
+                                                 : ", _bb)");
+    } else {
+      key_offset += GenByteBufferLength("bb");
+      key_offset += " - tableOffset, bb)";
+    }
+    return key_offset;
+  }
+
+  std::string GenLookupKeyGetter(flatbuffers::FieldDef *key_field) const {
+    std::string key_getter = "      ";
+    key_getter += "int tableOffset = " + lang_.accessor_prefix_static;
+    key_getter += "__indirect(vectorLocation + 4 * (start + middle)";
+    key_getter += ", bb);\n      ";
+    if (key_field->value.type.base_type == BASE_TYPE_STRING) {
+      key_getter += "int comp = " + lang_.accessor_prefix_static;
+      key_getter += FunctionStart('C') + "ompareStrings(";
+      key_getter += GenOffsetGetter(key_field);
+      key_getter += ", byteKey, bb);\n";
+    } else {
+      auto get_val = GenGetterForLookupByKey(key_field, "bb");
+      if (lang_.language == IDLOptions::kCSharp) {
+        key_getter += "int comp = " + get_val + ".CompareTo(key);\n";
+      } else {
+        key_getter += GenTypeNameDest(key_field->value.type) + " val = ";
+        key_getter += get_val + ";\n";
+        key_getter += "      int comp = val > key ? 1 : val < key ? -1 : 0;\n";
+      }
+    }
+    return key_getter;
+  }
+
+  std::string GenKeyGetter(flatbuffers::FieldDef *key_field) const {
+    std::string key_getter = "";
+    auto data_buffer =
+        (lang_.language == IDLOptions::kCSharp) ? "builder.DataBuffer" : "_bb";
+    if (key_field->value.type.base_type == BASE_TYPE_STRING) {
+      if (lang_.language == IDLOptions::kJava) key_getter += " return ";
+      key_getter += lang_.accessor_prefix_static;
+      key_getter += FunctionStart('C') + "ompareStrings(";
+      key_getter += GenOffsetGetter(key_field, "o1") + ", ";
+      key_getter += GenOffsetGetter(key_field, "o2") + ", " + data_buffer + ")";
+      if (lang_.language == IDLOptions::kJava) key_getter += ";";
+    } else {
+      auto field_getter = GenGetterForLookupByKey(key_field, data_buffer, "o1");
+      if (lang_.language == IDLOptions::kCSharp) {
+        key_getter += field_getter;
+        field_getter = GenGetterForLookupByKey(key_field, data_buffer, "o2");
+        key_getter += ".CompareTo(" + field_getter + ")";
+      } else {
+        key_getter +=
+            "\n    " + GenTypeNameDest(key_field->value.type) + " val_1 = ";
+        key_getter +=
+            field_getter + ";\n    " + GenTypeNameDest(key_field->value.type);
+        key_getter += " val_2 = ";
+        field_getter = GenGetterForLookupByKey(key_field, data_buffer, "o2");
+        key_getter += field_getter + ";\n";
+        key_getter +=
+            "    return val_1 > val_2 ? 1 : val_1 < val_2 ? -1 : 0;\n ";
+      }
+    }
+    return key_getter;
+  }
+
+  void GenStruct(StructDef &struct_def, std::string *code_ptr) const {
+    if (struct_def.generated) return;
+    std::string &code = *code_ptr;
+
+    // Generate a struct accessor class, with methods of the form:
+    // public type name() { return bb.getType(i + offset); }
+    // or for tables of the form:
+    // public type name() {
+    //   int o = __offset(offset); return o != 0 ? bb.getType(o + i) : default;
+    // }
+    GenComment(struct_def.doc_comment, code_ptr, &lang_.comment_config);
+    if (struct_def.attributes.Lookup("private")) {
+      // For Java, we leave the struct unmarked to indicate package-private
+      // For C# we mark the struct as internal
+      if (lang_.language == IDLOptions::kCSharp) {
+        code += "internal ";
+      }
+    } else {
+      code += "public ";
+    }
+    if (lang_.language == IDLOptions::kCSharp &&
+        struct_def.attributes.Lookup("csharp_partial")) {
+      // generate a partial class for this C# struct/table
+      code += "partial ";
+    } else {
+      code += lang_.unsubclassable_decl;
+    }
+    code += lang_.accessor_type + struct_def.name;
+    if (lang_.language == IDLOptions::kCSharp) {
+      code += " : IFlatbufferObject";
+      code += lang_.open_curly;
+      code += "  private ";
+      code += struct_def.fixed ? "Struct" : "Table";
+      code += " __p;\n";
+
+      if (lang_.language == IDLOptions::kCSharp) {
+        code += "  public ByteBuffer ByteBuffer { get { return __p.bb; } }\n";
+      }
+
+    } else {
+      code += lang_.inheritance_marker;
+      code += struct_def.fixed ? "Struct" : "Table";
+      code += lang_.open_curly;
+    }
+
+    if (!struct_def.fixed) {
+      // Generate verson check method.
+      // Force compile time error if not using the same version runtime.
+      code += "  public static void ValidateVersion() {";
+      if (lang_.language == IDLOptions::kCSharp)
+        code += " FlatBufferConstants.";
+      else
+        code += " Constants.";
+      code += "FLATBUFFERS_1_11_1(); ";
+      code += "}\n";
+
+      // Generate a special accessor for the table that when used as the root
+      // of a FlatBuffer
+      std::string method_name =
+          FunctionStart('G') + "etRootAs" + struct_def.name;
+      std::string method_signature =
+          "  public static " + struct_def.name + " " + method_name;
+
+      // create convenience method that doesn't require an existing object
+      code += method_signature + "(ByteBuffer _bb) ";
+      code += "{ return " + method_name + "(_bb, new " + struct_def.name +
+              "()); }\n";
+
+      // create method that allows object reuse
+      code +=
+          method_signature + "(ByteBuffer _bb, " + struct_def.name + " obj) { ";
+      code += lang_.set_bb_byteorder;
+      code += "return (obj.__assign(_bb." + FunctionStart('G') + "etInt(_bb.";
+      code += lang_.get_bb_position;
+      code += ") + _bb.";
+      code += lang_.get_bb_position;
+      code += ", _bb)); }\n";
+      if (parser_.root_struct_def_ == &struct_def) {
+        if (parser_.file_identifier_.length()) {
+          // Check if a buffer has the identifier.
+          code += "  public static ";
+          code += lang_.bool_type + struct_def.name;
+          code += "BufferHasIdentifier(ByteBuffer _bb) { return ";
+          code += lang_.accessor_prefix_static + "__has_identifier(_bb, \"";
+          code += parser_.file_identifier_;
+          code += "\"); }\n";
+        }
+      }
+    }
+    // Generate the __init method that sets the field in a pre-existing
+    // accessor object. This is to allow object reuse.
+    code += "  public void __init(int _i, ByteBuffer _bb) ";
+    code += "{ ";
+    if (lang_.language == IDLOptions::kCSharp) {
+      code += "__p = new ";
+      code += struct_def.fixed ? "Struct" : "Table";
+      code += "(_i, _bb); ";
+    } else {
+      code += "__reset(_i, _bb); ";
+    }
+    code += "}\n";
+    code +=
+        "  public " + struct_def.name + " __assign(int _i, ByteBuffer _bb) ";
+    code += "{ __init(_i, _bb); return this; }\n\n";
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+      GenComment(field.doc_comment, code_ptr, &lang_.comment_config, "  ");
+      std::string type_name = GenTypeGet(field.value.type);
+      std::string type_name_dest = GenTypeNameDest(field.value.type);
+      std::string conditional_cast = "";
+      std::string optional = "";
+      if (lang_.language == IDLOptions::kCSharp && !struct_def.fixed &&
+          (field.value.type.base_type == BASE_TYPE_STRUCT ||
+           field.value.type.base_type == BASE_TYPE_UNION ||
+           (field.value.type.base_type == BASE_TYPE_VECTOR &&
+            (field.value.type.element == BASE_TYPE_STRUCT ||
+             field.value.type.element == BASE_TYPE_UNION)))) {
+        optional = lang_.optional_suffix;
+        conditional_cast = "(" + type_name_dest + optional + ")";
+      }
+      std::string dest_mask = DestinationMask(field.value.type, true);
+      std::string dest_cast = DestinationCast(field.value.type);
+      std::string src_cast = SourceCast(field.value.type);
+      std::string method_start = "  public " +
+                                 (field.required ? "" : GenNullableAnnotation(field.value.type)) +
+                                 type_name_dest + optional + " " +
+                                 MakeCamel(field.name, lang_.first_camel_upper);
+      std::string obj = lang_.language == IDLOptions::kCSharp
+                            ? "(new " + type_name + "())"
+                            : "obj";
+
+      // Most field accessors need to retrieve and test the field offset first,
+      // this is the prefix code for that:
+      auto offset_prefix =
+          IsArray(field.value.type)
+              ? " { return "
+              : (" { int o = " + lang_.accessor_prefix + "__offset(" +
+                 NumToString(field.value.offset) + "); return o != 0 ? ");
+      // Generate the accessors that don't do object reuse.
+      if (field.value.type.base_type == BASE_TYPE_STRUCT) {
+        // Calls the accessor that takes an accessor object with a new object.
+        if (lang_.language != IDLOptions::kCSharp) {
+          code += method_start + "() { return ";
+          code += MakeCamel(field.name, lang_.first_camel_upper);
+          code += "(new ";
+          code += type_name + "()); }\n";
+        }
+      } else if (field.value.type.base_type == BASE_TYPE_VECTOR &&
+                 field.value.type.element == BASE_TYPE_STRUCT) {
+        // Accessors for vectors of structs also take accessor objects, this
+        // generates a variant without that argument.
+        if (lang_.language != IDLOptions::kCSharp) {
+          code += method_start + "(int j) { return ";
+          code += MakeCamel(field.name, lang_.first_camel_upper);
+          code += "(new " + type_name + "(), j); }\n";
+        }
+      } else if (field.value.type.base_type == BASE_TYPE_UNION ||
+          (field.value.type.base_type == BASE_TYPE_VECTOR &&
+           field.value.type.VectorType().base_type == BASE_TYPE_UNION)) {
+        if (lang_.language == IDLOptions::kCSharp) {
+          // Union types in C# use generic Table-derived type for better type
+          // safety.
+          method_start += "<TTable>";
+          type_name = type_name_dest;
+        }
+      }
+      std::string getter = dest_cast + GenGetter(field.value.type);
+      code += method_start;
+      std::string default_cast = "";
+      // only create default casts for c# scalars or vectors of scalars
+      if (lang_.language == IDLOptions::kCSharp &&
+          (IsScalar(field.value.type.base_type) ||
+           (field.value.type.base_type == BASE_TYPE_VECTOR &&
+            IsScalar(field.value.type.element)))) {
+        // For scalars, default value will be returned by GetDefaultValue().
+        // If the scalar is an enum, GetDefaultValue() returns an actual c# enum
+        // that doesn't need to be casted. However, default values for enum
+        // elements of vectors are integer literals ("0") and are still casted
+        // for clarity.
+        if (field.value.type.enum_def == nullptr ||
+            field.value.type.base_type == BASE_TYPE_VECTOR) {
+          default_cast = "(" + type_name_dest + ")";
+        }
+      }
+      std::string member_suffix = "; ";
+      if (IsScalar(field.value.type.base_type)) {
+        code += lang_.getter_prefix;
+        member_suffix += lang_.getter_suffix;
+        if (struct_def.fixed) {
+          code += " { return " + getter;
+          code += "(" + lang_.accessor_prefix + "bb_pos + ";
+          code += NumToString(field.value.offset) + ")";
+          code += dest_mask;
+        } else {
+          code += offset_prefix + getter;
+          code += "(o + " + lang_.accessor_prefix + "bb_pos)" + dest_mask;
+          code += " : " + default_cast;
+          code += GenDefaultValue(field);
+        }
+      } else {
+        switch (field.value.type.base_type) {
+          case BASE_TYPE_STRUCT:
+            if (lang_.language != IDLOptions::kCSharp) {
+              code += "(" + type_name + " obj" + ")";
+            } else {
+              code += lang_.getter_prefix;
+              member_suffix += lang_.getter_suffix;
+            }
+            if (struct_def.fixed) {
+              code += " { return " + obj + ".__assign(" + lang_.accessor_prefix;
+              code += "bb_pos + " + NumToString(field.value.offset) + ", ";
+              code += lang_.accessor_prefix + "bb)";
+            } else {
+              code += offset_prefix + conditional_cast;
+              code += obj + ".__assign(";
+              code += field.value.type.struct_def->fixed
+                          ? "o + " + lang_.accessor_prefix + "bb_pos"
+                          : lang_.accessor_prefix + "__indirect(o + " +
+                                lang_.accessor_prefix + "bb_pos)";
+              code += ", " + lang_.accessor_prefix + "bb) : null";
+            }
+            break;
+          case BASE_TYPE_STRING:
+            code += lang_.getter_prefix;
+            member_suffix += lang_.getter_suffix;
+            code += offset_prefix + getter + "(o + " + lang_.accessor_prefix;
+            code += "bb_pos) : null";
+            break;
+          case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH();  // fall thru
+          case BASE_TYPE_VECTOR: {
+            auto vectortype = field.value.type.VectorType();
+            if (vectortype.base_type == BASE_TYPE_UNION &&
+                lang_.language == IDLOptions::kCSharp) {
+                  conditional_cast = "(TTable?)";
+                  getter += "<TTable>";
+            }
+            code += "(";
+            if (vectortype.base_type == BASE_TYPE_STRUCT) {
+              if (lang_.language != IDLOptions::kCSharp)
+                code += type_name + " obj, ";
+              getter = obj + ".__assign";
+            } else if (vectortype.base_type == BASE_TYPE_UNION) {
+              if (lang_.language != IDLOptions::kCSharp)
+                code += type_name + " obj, ";
+            }
+            code += "int j)";
+            const auto body = offset_prefix + conditional_cast + getter + "(";
+            if (vectortype.base_type == BASE_TYPE_UNION) {
+              if (lang_.language != IDLOptions::kCSharp)
+                code += body + "obj, ";
+              else
+                code += " where TTable : struct, IFlatbufferObject" + body;
+            } else {
+              code += body;
+            }
+            auto index = lang_.accessor_prefix;
+            if (IsArray(field.value.type)) {
+              index += "bb_pos + " + NumToString(field.value.offset) + " + ";
+            } else {
+              index += "__vector(o) + ";
+            }
+            index += "j * " + NumToString(InlineSize(vectortype));
+            if (vectortype.base_type == BASE_TYPE_STRUCT) {
+              code += vectortype.struct_def->fixed
+                          ? index
+                          : lang_.accessor_prefix + "__indirect(" + index + ")";
+              code += ", " + lang_.accessor_prefix + "bb";
+            } else if (vectortype.base_type == BASE_TYPE_UNION) {
+              code += index + " - " + lang_.accessor_prefix +  "bb_pos";
+            } else {
+              code += index;
+            }
+            code += ")" + dest_mask;
+            if (!IsArray(field.value.type)) {
+              code += " : ";
+              code +=
+                  field.value.type.element == BASE_TYPE_BOOL
+                      ? "false"
+                      : (IsScalar(field.value.type.element) ? default_cast + "0"
+                                                            : "null");
+            }
+
+            break;
+          }
+          case BASE_TYPE_UNION:
+            if (lang_.language == IDLOptions::kCSharp) {
+              code += "() where TTable : struct, IFlatbufferObject";
+              code += offset_prefix + "(TTable?)" + getter;
+              code += "<TTable>(o) : null";
+            } else {
+              code += "(" + type_name + " obj)" + offset_prefix + getter;
+              code += "(obj, o) : null";
+            }
+            break;
+          default: FLATBUFFERS_ASSERT(0);
+        }
+      }
+      code += member_suffix;
+      code += "}\n";
+      if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+        code +=
+            "  public int " + MakeCamel(field.name, lang_.first_camel_upper);
+        code += "Length";
+        code += lang_.getter_prefix;
+        code += offset_prefix;
+        code += lang_.accessor_prefix + "__vector_len(o) : 0; ";
+        code += lang_.getter_suffix;
+        code += "}\n";
+        // See if we should generate a by-key accessor.
+        if (field.value.type.element == BASE_TYPE_STRUCT &&
+            !field.value.type.struct_def->fixed) {
+          auto &sd = *field.value.type.struct_def;
+          auto &fields = sd.fields.vec;
+          for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
+            auto &key_field = **kit;
+            if (key_field.key) {
+              auto qualified_name = WrapInNameSpace(sd);
+              code += "  public " + qualified_name + lang_.optional_suffix + " ";
+              code += MakeCamel(field.name, lang_.first_camel_upper) + "ByKey(";
+              code += GenTypeNameDest(key_field.value.type) + " key)";
+              code += offset_prefix;
+              code += qualified_name + ".__lookup_by_key(";
+              if (lang_.language == IDLOptions::kJava)
+                code += "null, ";
+              code += lang_.accessor_prefix + "__vector(o), key, ";
+              code += lang_.accessor_prefix + "bb) : null; ";
+              code += "}\n";
+              if (lang_.language == IDLOptions::kJava) {
+                code += "  public " + qualified_name + lang_.optional_suffix + " ";
+                code += MakeCamel(field.name, lang_.first_camel_upper) + "ByKey(";
+                code += qualified_name + lang_.optional_suffix + " obj, ";
+                code += GenTypeNameDest(key_field.value.type) + " key)";
+                code += offset_prefix;
+                code += qualified_name + ".__lookup_by_key(obj, ";
+                code += lang_.accessor_prefix + "__vector(o), key, ";
+                code += lang_.accessor_prefix + "bb) : null; ";
+                code += "}\n";
+              }
+              break;
+            }
+          }
+        }
+      }
+      // Generate a ByteBuffer accessor for strings & vectors of scalars.
+      if ((field.value.type.base_type == BASE_TYPE_VECTOR &&
+           IsScalar(field.value.type.VectorType().base_type)) ||
+          field.value.type.base_type == BASE_TYPE_STRING) {
+        switch (lang_.language) {
+          case IDLOptions::kJava:
+            code += "  public ByteBuffer ";
+            code += MakeCamel(field.name, lang_.first_camel_upper);
+            code += "AsByteBuffer() { return ";
+            code += lang_.accessor_prefix + "__vector_as_bytebuffer(";
+            code += NumToString(field.value.offset) + ", ";
+            code +=
+                NumToString(field.value.type.base_type == BASE_TYPE_STRING
+                                ? 1
+                                : InlineSize(field.value.type.VectorType()));
+            code += "); }\n";
+            code += "  public ByteBuffer ";
+            code += MakeCamel(field.name, lang_.first_camel_upper);
+            code += "InByteBuffer(ByteBuffer _bb) { return ";
+            code += lang_.accessor_prefix + "__vector_in_bytebuffer(_bb, ";
+            code += NumToString(field.value.offset) + ", ";
+            code +=
+                NumToString(field.value.type.base_type == BASE_TYPE_STRING
+                                ? 1
+                                : InlineSize(field.value.type.VectorType()));
+            code += "); }\n";
+            break;
+          case IDLOptions::kCSharp:
+            code += "#if ENABLE_SPAN_T\n";
+            code += "  public Span<byte> Get";
+            code += MakeCamel(field.name, lang_.first_camel_upper);
+            code += "Bytes() { return ";
+            code += lang_.accessor_prefix + "__vector_as_span(";
+            code += NumToString(field.value.offset);
+            code += "); }\n";
+            code += "#else\n";
+            code += "  public ArraySegment<byte>? Get";
+            code += MakeCamel(field.name, lang_.first_camel_upper);
+            code += "Bytes() { return ";
+            code += lang_.accessor_prefix + "__vector_as_arraysegment(";
+            code += NumToString(field.value.offset);
+            code += "); }\n";
+            code += "#endif\n";
+
+            // For direct blockcopying the data into a typed array
+            code += "  public ";
+            code += GenTypeBasic(field.value.type.VectorType());
+            code += "[] Get";
+            code += MakeCamel(field.name, lang_.first_camel_upper);
+            code += "Array() { return ";
+            code += lang_.accessor_prefix + "__vector_as_array<";
+            code += GenTypeBasic(field.value.type.VectorType());
+            code += ">(";
+            code += NumToString(field.value.offset);
+            code += "); }\n";
+            break;
+          default: break;
+        }
+      }
+      // generate object accessors if is nested_flatbuffer
+      if (field.nested_flatbuffer) {
+        auto nested_type_name = WrapInNameSpace(*field.nested_flatbuffer);
+        auto nested_method_name =
+            MakeCamel(field.name, lang_.first_camel_upper) + "As" +
+            field.nested_flatbuffer->name;
+        auto get_nested_method_name = nested_method_name;
+        if (lang_.language == IDLOptions::kCSharp) {
+          get_nested_method_name = "Get" + nested_method_name;
+          conditional_cast =
+              "(" + nested_type_name + lang_.optional_suffix + ")";
+        }
+        if (lang_.language != IDLOptions::kCSharp) {
+          code += "  public " + nested_type_name + lang_.optional_suffix + " ";
+          code += nested_method_name + "() { return ";
+          code +=
+              get_nested_method_name + "(new " + nested_type_name + "()); }\n";
+        } else {
+          obj = "(new " + nested_type_name + "())";
+        }
+        code += "  public " + nested_type_name + lang_.optional_suffix + " ";
+        code += get_nested_method_name + "(";
+        if (lang_.language != IDLOptions::kCSharp)
+          code += nested_type_name + " obj";
+        code += ") { int o = " + lang_.accessor_prefix + "__offset(";
+        code += NumToString(field.value.offset) + "); ";
+        code += "return o != 0 ? " + conditional_cast + obj + ".__assign(";
+        code += lang_.accessor_prefix;
+        code += "__indirect(" + lang_.accessor_prefix + "__vector(o)), ";
+        code += lang_.accessor_prefix + "bb) : null; }\n";
+      }
+      // Generate mutators for scalar fields or vectors of scalars.
+      if (parser_.opts.mutable_buffer) {
+        auto is_series = (IsSeries(field.value.type));
+        const auto &underlying_type =
+            is_series ? field.value.type.VectorType() : field.value.type;
+        // Boolean parameters have to be explicitly converted to byte
+        // representation.
+        auto setter_parameter = underlying_type.base_type == BASE_TYPE_BOOL
+                                    ? "(byte)(" + field.name + " ? 1 : 0)"
+                                    : field.name;
+        auto mutator_prefix = MakeCamel("mutate", lang_.first_camel_upper);
+        // A vector mutator also needs the index of the vector element it should
+        // mutate.
+        auto mutator_params = (is_series ? "(int j, " : "(") +
+                              GenTypeNameDest(underlying_type) + " " +
+                              field.name + ") { ";
+        auto setter_index =
+            is_series
+                ? lang_.accessor_prefix +
+                      (IsArray(field.value.type)
+                           ? "bb_pos + " + NumToString(field.value.offset)
+                           : "__vector(o)") +
+                      +" + j * " + NumToString(InlineSize(underlying_type))
+                : (struct_def.fixed
+                       ? lang_.accessor_prefix + "bb_pos + " +
+                             NumToString(field.value.offset)
+                       : "o + " + lang_.accessor_prefix + "bb_pos");
+        if (IsScalar(underlying_type.base_type)) {
+          code += "  public ";
+          code += struct_def.fixed ? "void " : lang_.bool_type;
+          code += mutator_prefix + MakeCamel(field.name, true);
+          code += mutator_params;
+          if (struct_def.fixed) {
+            code += GenSetter(underlying_type) + "(" + setter_index + ", ";
+            code += src_cast + setter_parameter + "); }\n";
+          } else {
+            code += "int o = " + lang_.accessor_prefix + "__offset(";
+            code += NumToString(field.value.offset) + ");";
+            code += " if (o != 0) { " + GenSetter(underlying_type);
+            code += "(" + setter_index + ", " + src_cast + setter_parameter +
+                    "); return true; } else { return false; } }\n";
+          }
+        }
+      }
+    }
+    code += "\n";
+    flatbuffers::FieldDef *key_field = nullptr;
+    if (struct_def.fixed) {
+      // create a struct constructor function
+      code += "  public static " + GenOffsetType(struct_def) + " ";
+      code += FunctionStart('C') + "reate";
+      code += struct_def.name + "(FlatBufferBuilder builder";
+      GenStructArgs(struct_def, code_ptr, "");
+      code += ") {\n";
+      GenStructBody(struct_def, code_ptr, "");
+      code += "    return ";
+      code += GenOffsetConstruct(
+          struct_def, "builder." + std::string(lang_.get_fbb_offset));
+      code += ";\n  }\n";
+    } else {
+      // Generate a method that creates a table in one go. This is only possible
+      // when the table has no struct fields, since those have to be created
+      // inline, and there's no way to do so in Java.
+      bool has_no_struct_fields = true;
+      int num_fields = 0;
+      for (auto it = struct_def.fields.vec.begin();
+           it != struct_def.fields.vec.end(); ++it) {
+        auto &field = **it;
+        if (field.deprecated) continue;
+        if (IsStruct(field.value.type)) {
+          has_no_struct_fields = false;
+        } else {
+          num_fields++;
+        }
+      }
+      // JVM specifications restrict default constructor params to be < 255.
+      // Longs and doubles take up 2 units, so we set the limit to be < 127.
+      if (has_no_struct_fields && num_fields && num_fields < 127) {
+        // Generate a table constructor of the form:
+        // public static int createName(FlatBufferBuilder builder, args...)
+        code += "  public static " + GenOffsetType(struct_def) + " ";
+        code += FunctionStart('C') + "reate" + struct_def.name;
+        code += "(FlatBufferBuilder builder";
+        for (auto it = struct_def.fields.vec.begin();
+             it != struct_def.fields.vec.end(); ++it) {
+          auto &field = **it;
+          if (field.deprecated) continue;
+          code += ",\n      ";
+          code += GenTypeBasic(DestinationType(field.value.type, false));
+          code += " ";
+          code += field.name;
+          if (!IsScalar(field.value.type.base_type)) code += "Offset";
+
+          // Java doesn't have defaults, which means this method must always
+          // supply all arguments, and thus won't compile when fields are added.
+          if (lang_.language != IDLOptions::kJava) {
+            code += " = ";
+            code += GenDefaultValueBasic(field);
+          }
+        }
+        code += ") {\n    builder.";
+        code += FunctionStart('S') + "tartTable(";
+        code += NumToString(struct_def.fields.vec.size()) + ");\n";
+        for (size_t size = struct_def.sortbysize ? sizeof(largest_scalar_t) : 1;
+             size; size /= 2) {
+          for (auto it = struct_def.fields.vec.rbegin();
+               it != struct_def.fields.vec.rend(); ++it) {
+            auto &field = **it;
+            if (!field.deprecated &&
+                (!struct_def.sortbysize ||
+                 size == SizeOf(field.value.type.base_type))) {
+              code += "    " + struct_def.name + ".";
+              code += FunctionStart('A') + "dd";
+              code += MakeCamel(field.name) + "(builder, " + field.name;
+              if (!IsScalar(field.value.type.base_type)) code += "Offset";
+              code += ");\n";
+            }
+          }
+        }
+        code += "    return " + struct_def.name + ".";
+        code += FunctionStart('E') + "nd" + struct_def.name;
+        code += "(builder);\n  }\n\n";
+      }
+      // Generate a set of static methods that allow table construction,
+      // of the form:
+      // public static void addName(FlatBufferBuilder builder, short name)
+      // { builder.addShort(id, name, default); }
+      // Unlike the Create function, these always work.
+      code += "  public static void " + FunctionStart('S') + "tart";
+      code += struct_def.name;
+      code += "(FlatBufferBuilder builder) { builder.";
+      code += FunctionStart('S') + "tartTable(";
+      code += NumToString(struct_def.fields.vec.size()) + "); }\n";
+      for (auto it = struct_def.fields.vec.begin();
+           it != struct_def.fields.vec.end(); ++it) {
+        auto &field = **it;
+        if (field.deprecated) continue;
+        if (field.key) key_field = &field;
+        code += "  public static void " + FunctionStart('A') + "dd";
+        code += MakeCamel(field.name);
+        code += "(FlatBufferBuilder builder, ";
+        code += GenTypeBasic(DestinationType(field.value.type, false));
+        auto argname = MakeCamel(field.name, false);
+        if (!IsScalar(field.value.type.base_type)) argname += "Offset";
+        code += " " + argname + ") { builder." + FunctionStart('A') + "dd";
+        code += GenMethod(field.value.type) + "(";
+        code += NumToString(it - struct_def.fields.vec.begin()) + ", ";
+        code += SourceCastBasic(field.value.type);
+        code += argname;
+        if (!IsScalar(field.value.type.base_type) &&
+            field.value.type.base_type != BASE_TYPE_UNION &&
+            lang_.language == IDLOptions::kCSharp) {
+          code += ".Value";
+        }
+        code += ", ";
+        if (lang_.language == IDLOptions::kJava)
+          code += SourceCastBasic(field.value.type);
+        code += GenDefaultValue(field, false);
+        code += "); }\n";
+        if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+          auto vector_type = field.value.type.VectorType();
+          auto alignment = InlineAlignment(vector_type);
+          auto elem_size = InlineSize(vector_type);
+          if (!IsStruct(vector_type)) {
+            // Generate a method to create a vector from a Java array.
+            code += "  public static " + GenVectorOffsetType() + " ";
+            code += FunctionStart('C') + "reate";
+            code += MakeCamel(field.name);
+            code += "Vector(FlatBufferBuilder builder, ";
+            code += GenTypeBasic(vector_type) + "[] data) ";
+            code += "{ builder." + FunctionStart('S') + "tartVector(";
+            code += NumToString(elem_size);
+            code += ", data." + FunctionStart('L') + "ength, ";
+            code += NumToString(alignment);
+            code += "); for (int i = data.";
+            code += FunctionStart('L') + "ength - 1; i >= 0; i--) builder.";
+            code += FunctionStart('A') + "dd";
+            code += GenMethod(vector_type);
+            code += "(";
+            code += SourceCastBasic(vector_type, false);
+            code += "data[i]";
+            if (lang_.language == IDLOptions::kCSharp &&
+                (vector_type.base_type == BASE_TYPE_STRUCT ||
+                 vector_type.base_type == BASE_TYPE_STRING))
+              code += ".Value";
+            code += "); return ";
+            code += "builder." + FunctionStart('E') + "ndVector(); }\n";
+            // For C#, include a block copy method signature.
+            if (lang_.language == IDLOptions::kCSharp) {
+              code += "  public static " + GenVectorOffsetType() + " ";
+              code += FunctionStart('C') + "reate";
+              code += MakeCamel(field.name);
+              code += "VectorBlock(FlatBufferBuilder builder, ";
+              code += GenTypeBasic(vector_type) + "[] data) ";
+              code += "{ builder." + FunctionStart('S') + "tartVector(";
+              code += NumToString(elem_size);
+              code += ", data." + FunctionStart('L') + "ength, ";
+              code += NumToString(alignment);
+              code += "); builder.Add(data); return builder.EndVector(); }\n";
+            }
+          }
+          // Generate a method to start a vector, data to be added manually
+          // after.
+          code += "  public static void " + FunctionStart('S') + "tart";
+          code += MakeCamel(field.name);
+          code += "Vector(FlatBufferBuilder builder, int numElems) ";
+          code += "{ builder." + FunctionStart('S') + "tartVector(";
+          code += NumToString(elem_size);
+          code += ", numElems, " + NumToString(alignment);
+          code += "); }\n";
+        }
+      }
+      code += "  public static " + GenOffsetType(struct_def) + " ";
+      code += FunctionStart('E') + "nd" + struct_def.name;
+      code += "(FlatBufferBuilder builder) {\n    int o = builder.";
+      code += FunctionStart('E') + "ndTable();\n";
+      for (auto it = struct_def.fields.vec.begin();
+           it != struct_def.fields.vec.end(); ++it) {
+        auto &field = **it;
+        if (!field.deprecated && field.required) {
+          code += "    builder." + FunctionStart('R') + "equired(o, ";
+          code += NumToString(field.value.offset);
+          code += ");  // " + field.name + "\n";
+        }
+      }
+      code += "    return " + GenOffsetConstruct(struct_def, "o") + ";\n  }\n";
+      if (parser_.root_struct_def_ == &struct_def) {
+        std::string size_prefix[] = { "", "SizePrefixed" };
+        for (int i = 0; i < 2; ++i) {
+          code += "  public static void ";
+          code += FunctionStart('F') + "inish" + size_prefix[i] +
+                  struct_def.name;
+          code += "Buffer(FlatBufferBuilder builder, " +
+                  GenOffsetType(struct_def);
+          code += " offset) {";
+          code += " builder." + FunctionStart('F') + "inish" + size_prefix[i] +
+                  "(offset";
+          if (lang_.language == IDLOptions::kCSharp) { code += ".Value"; }
+
+          if (parser_.file_identifier_.length())
+            code += ", \"" + parser_.file_identifier_ + "\"";
+          code += "); }\n";
+        }
+      }
+    }
+    // Only generate key compare function for table,
+    // because `key_field` is not set for struct
+    if (struct_def.has_key && !struct_def.fixed) {
+      FLATBUFFERS_ASSERT(key_field);
+      if (lang_.language == IDLOptions::kJava) {
+        code += "\n  @Override\n  protected int keysCompare(";
+        code += "Integer o1, Integer o2, ByteBuffer _bb) {";
+        code += GenKeyGetter(key_field);
+        code += " }\n";
+      } else {
+        code += "\n  public static VectorOffset ";
+        code += "CreateSortedVectorOf" + struct_def.name;
+        code += "(FlatBufferBuilder builder, ";
+        code += "Offset<" + struct_def.name + ">";
+        code += "[] offsets) {\n";
+        code += "    Array.Sort(offsets, (Offset<" + struct_def.name +
+                "> o1, Offset<" + struct_def.name + "> o2) => " +
+                GenKeyGetter(key_field);
+        code += ");\n";
+        code += "    return builder.CreateVectorOfTables(offsets);\n  }\n";
+      }
+
+      code += "\n  public static " + struct_def.name + lang_.optional_suffix;
+      code += " __lookup_by_key(";
+      if (lang_.language == IDLOptions::kJava)
+        code +=  struct_def.name + " obj, ";
+      code += "int vectorLocation, ";
+      code += GenTypeNameDest(key_field->value.type);
+      code += " key, ByteBuffer bb) {\n";
+      if (key_field->value.type.base_type == BASE_TYPE_STRING) {
+        code += "    byte[] byteKey = ";
+        if (lang_.language == IDLOptions::kJava)
+          code += "key.getBytes(Table.UTF8_CHARSET.get());\n";
+        else
+          code += "System.Text.Encoding.UTF8.GetBytes(key);\n";
+      }
+      code += "    int span = ";
+      code += "bb." + FunctionStart('G') + "etInt(vectorLocation - 4);\n";
+      code += "    int start = 0;\n";
+      code += "    while (span != 0) {\n";
+      code += "      int middle = span / 2;\n";
+      code += GenLookupKeyGetter(key_field);
+      code += "      if (comp > 0) {\n";
+      code += "        span = middle;\n";
+      code += "      } else if (comp < 0) {\n";
+      code += "        middle++;\n";
+      code += "        start += middle;\n";
+      code += "        span -= middle;\n";
+      code += "      } else {\n";
+      code += "        return ";
+      if (lang_.language == IDLOptions::kJava)
+        code += "(obj == null ? new " + struct_def.name + "() : obj)";
+      else
+        code += "new " + struct_def.name + "()";
+      code += ".__assign(tableOffset, bb);\n";
+      code += "      }\n    }\n";
+      code += "    return null;\n";
+      code += "  }\n";
+    }
+    code += "}";
+    // Java does not need the closing semi-colon on class definitions.
+    code += (lang_.language != IDLOptions::kJava) ? ";" : "";
+    code += "\n\n";
+  }
+  const LanguageParameters &lang_;
+  // This tracks the current namespace used to determine if a type need to be
+  // prefixed by its namespace
+  const Namespace *cur_name_space_;
+};
+}  // namespace general
+
+bool GenerateGeneral(const Parser &parser, const std::string &path,
+                     const std::string &file_name) {
+  general::GeneralGenerator generator(parser, path, file_name);
+  return generator.generate();
+}
+
+std::string GeneralMakeRule(const Parser &parser, const std::string &path,
+                            const std::string &file_name) {
+  FLATBUFFERS_ASSERT(parser.opts.lang <= IDLOptions::kMAX);
+  const auto &lang = GetLangParams(parser.opts.lang);
+
+  std::string make_rule;
+
+  for (auto it = parser.enums_.vec.begin(); it != parser.enums_.vec.end();
+       ++it) {
+    auto &enum_def = **it;
+    if (!make_rule.empty()) make_rule += " ";
+    std::string directory =
+        BaseGenerator::NamespaceDir(parser, path, *enum_def.defined_namespace);
+    make_rule += directory + enum_def.name + lang.file_extension;
+  }
+
+  for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end();
+       ++it) {
+    auto &struct_def = **it;
+    if (!make_rule.empty()) make_rule += " ";
+    std::string directory = BaseGenerator::NamespaceDir(
+        parser, path, *struct_def.defined_namespace);
+    make_rule += directory + struct_def.name + lang.file_extension;
+  }
+
+  make_rule += ": ";
+  auto included_files = parser.GetIncludedFilesRecursive(file_name);
+  for (auto it = included_files.begin(); it != included_files.end(); ++it) {
+    make_rule += " " + *it;
+  }
+  return make_rule;
+}
+
+std::string BinaryFileName(const Parser &parser, const std::string &path,
+                           const std::string &file_name) {
+  auto ext = parser.file_extension_.length() ? parser.file_extension_ : "bin";
+  return path + file_name + "." + ext;
+}
+
+bool GenerateBinary(const Parser &parser, const std::string &path,
+                    const std::string &file_name) {
+  return !parser.builder_.GetSize() ||
+         flatbuffers::SaveFile(
+             BinaryFileName(parser, path, file_name).c_str(),
+             reinterpret_cast<char *>(parser.builder_.GetBufferPointer()),
+             parser.builder_.GetSize(), true);
+}
+
+std::string BinaryMakeRule(const Parser &parser, const std::string &path,
+                           const std::string &file_name) {
+  if (!parser.builder_.GetSize()) return "";
+  std::string filebase =
+      flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
+  std::string make_rule =
+      BinaryFileName(parser, path, filebase) + ": " + file_name;
+  auto included_files =
+      parser.GetIncludedFilesRecursive(parser.root_struct_def_->file);
+  for (auto it = included_files.begin(); it != included_files.end(); ++it) {
+    make_rule += " " + *it;
+  }
+  return make_rule;
+}
+
+}  // namespace flatbuffers
diff --git a/src/idl_gen_go.cpp b/src/idl_gen_go.cpp
new file mode 100644
index 0000000..5e62b61
--- /dev/null
+++ b/src/idl_gen_go.cpp
@@ -0,0 +1,1009 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// independent from idl_parser, since this code is not needed for most clients
+
+#include <sstream>
+#include <string>
+
+#include "flatbuffers/code_generators.h"
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+#ifdef _WIN32
+#  include <direct.h>
+#  define PATH_SEPARATOR "\\"
+#  define mkdir(n, m) _mkdir(n)
+#else
+#  include <sys/stat.h>
+#  define PATH_SEPARATOR "/"
+#endif
+
+namespace flatbuffers {
+
+static std::string GeneratedFileName(const std::string &path,
+                                     const std::string &file_name) {
+  return path + file_name + "_generated.go";
+}
+
+namespace go {
+
+// see https://golang.org/ref/spec#Keywords
+static const char * const g_golang_keywords[] = {
+  "break",  "default", "func",        "interface", "select", "case", "defer",
+  "go",     "map",     "struct",      "chan",      "else",   "goto", "package",
+  "switch", "const",   "fallthrough", "if",        "range",  "type", "continue",
+  "for",    "import",  "return",      "var",
+};
+
+static std::string GoIdentity(const std::string &name) {
+  for (size_t i = 0;
+       i < sizeof(g_golang_keywords) / sizeof(g_golang_keywords[0]); i++) {
+    if (name == g_golang_keywords[i]) { return MakeCamel(name + "_", false); }
+  }
+
+  return MakeCamel(name, false);
+}
+
+class GoGenerator : public BaseGenerator {
+ public:
+  GoGenerator(const Parser &parser, const std::string &path,
+              const std::string &file_name, const std::string &go_namespace)
+      : BaseGenerator(parser, path, file_name, "" /* not used*/,
+                      "" /* not used */),
+        cur_name_space_(nullptr) {
+    std::istringstream iss(go_namespace);
+    std::string component;
+    while (std::getline(iss, component, '.')) {
+      go_namespace_.components.push_back(component);
+    }
+  }
+
+  bool generate() {
+    std::string one_file_code;
+    for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
+         ++it) {
+      tracked_imported_namespaces_.clear();
+      std::string enumcode;
+      GenEnum(**it, &enumcode);
+      if (parser_.opts.one_file) {
+        one_file_code += enumcode;
+      } else {
+        if (!SaveType(**it, enumcode, false, true)) return false;
+      }
+    }
+
+    for (auto it = parser_.structs_.vec.begin();
+         it != parser_.structs_.vec.end(); ++it) {
+      tracked_imported_namespaces_.clear();
+      std::string declcode;
+      GenStruct(**it, &declcode);
+      if (parser_.opts.one_file) {
+        one_file_code += declcode;
+      } else {
+        if (!SaveType(**it, declcode, true, false)) return false;
+      }
+    }
+
+    if (parser_.opts.one_file) {
+      std::string code = "";
+      const bool is_enum = !parser_.enums_.vec.empty();
+      BeginFile(LastNamespacePart(go_namespace_), true, is_enum, &code);
+      code += one_file_code;
+      const std::string filename = GeneratedFileName(path_, file_name_);
+      return SaveFile(filename.c_str(), code, false);
+    }
+
+    return true;
+  }
+
+ private:
+  Namespace go_namespace_;
+  Namespace *cur_name_space_;
+
+  struct NamespacePtrLess {
+    bool operator()(const Namespace *a, const Namespace *b) const {
+      return *a < *b;
+    }
+  };
+  std::set<const Namespace *, NamespacePtrLess> tracked_imported_namespaces_;
+
+  // Most field accessors need to retrieve and test the field offset first,
+  // this is the prefix code for that.
+  std::string OffsetPrefix(const FieldDef &field) {
+    return "{\n\to := flatbuffers.UOffsetT(rcv._tab.Offset(" +
+           NumToString(field.value.offset) + "))\n\tif o != 0 {\n";
+  }
+
+  // Begin a class declaration.
+  void BeginClass(const StructDef &struct_def, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    code += "type " + struct_def.name + " struct {\n\t";
+
+    // _ is reserved in flatbuffers field names, so no chance of name conflict:
+    code += "_tab ";
+    code += struct_def.fixed ? "flatbuffers.Struct" : "flatbuffers.Table";
+    code += "\n}\n\n";
+  }
+
+  // Construct the name of the type for this enum.
+  std::string GetEnumTypeName(const EnumDef &enum_def) {
+    return WrapInNameSpaceAndTrack(enum_def.defined_namespace, GoIdentity(enum_def.name));
+  }
+
+  // Create a type for the enum values.
+  void GenEnumType(const EnumDef &enum_def, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "type " + GetEnumTypeName(enum_def) + " ";
+    code += GenTypeBasic(enum_def.underlying_type) + "\n\n";
+  }
+
+  // Begin enum code with a class declaration.
+  void BeginEnum(std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "const (\n";
+  }
+
+  // A single enum member.
+  void EnumMember(const EnumDef &enum_def, const EnumVal &ev,
+                  size_t max_name_length, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "\t";
+    code += enum_def.name;
+    code += ev.name;
+    code += " ";
+    code += std::string(max_name_length - ev.name.length(), ' ');
+    code += GetEnumTypeName(enum_def);
+    code += " = ";
+    code += enum_def.ToString(ev) + "\n";
+  }
+
+  // End enum code.
+  void EndEnum(std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += ")\n\n";
+  }
+
+  // Begin enum name map.
+  void BeginEnumNames(const EnumDef &enum_def, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "var EnumNames";
+    code += enum_def.name;
+    code += " = map[" + GetEnumTypeName(enum_def) + "]string{\n";
+  }
+
+  // A single enum name member.
+  void EnumNameMember(const EnumDef &enum_def, const EnumVal &ev,
+                      size_t max_name_length, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "\t";
+    code += enum_def.name;
+    code += ev.name;
+    code += ": ";
+    code += std::string(max_name_length - ev.name.length(), ' ');
+    code += "\"";
+    code += ev.name;
+    code += "\",\n";
+  }
+
+  // End enum name map.
+  void EndEnumNames(std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "}\n\n";
+  }
+
+  // Generate String() method on enum type.
+  void EnumStringer(const EnumDef &enum_def, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "func (v " + enum_def.name + ") String() string {\n";
+    code += "\tif s, ok := EnumNames" + enum_def.name + "[v]; ok {\n";
+    code += "\t\treturn s\n";
+    code += "\t}\n";
+    code += "\treturn \""+ enum_def.name;
+    code += "(\" + strconv.FormatInt(int64(v), 10) + \")\"\n";
+    code += "}\n\n";
+  }
+
+  // Begin enum value map.
+  void BeginEnumValues(const EnumDef &enum_def, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "var EnumValues";
+    code += enum_def.name;
+    code += " = map[string]" + GetEnumTypeName(enum_def) + "{\n";
+  }
+
+  // A single enum value member.
+  void EnumValueMember(const EnumDef &enum_def, const EnumVal &ev,
+                       size_t max_name_length, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "\t\"";
+    code += ev.name;
+    code += "\": ";
+    code += std::string(max_name_length - ev.name.length(), ' ');
+    code += enum_def.name;
+    code += ev.name;
+    code += ",\n";
+  }
+
+  // End enum value map.
+  void EndEnumValues(std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "}\n\n";
+  }
+
+  // Initialize a new struct or table from existing data.
+  void NewRootTypeFromBuffer(const StructDef &struct_def,
+                             std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    code += "func GetRootAs";
+    code += struct_def.name;
+    code += "(buf []byte, offset flatbuffers.UOffsetT) ";
+    code += "*" + struct_def.name + "";
+    code += " {\n";
+    code += "\tn := flatbuffers.GetUOffsetT(buf[offset:])\n";
+    code += "\tx := &" + struct_def.name + "{}\n";
+    code += "\tx.Init(buf, n+offset)\n";
+    code += "\treturn x\n";
+    code += "}\n\n";
+  }
+
+  // Initialize an existing object with other data, to avoid an allocation.
+  void InitializeExisting(const StructDef &struct_def, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    GenReceiver(struct_def, code_ptr);
+    code += " Init(buf []byte, i flatbuffers.UOffsetT) ";
+    code += "{\n";
+    code += "\trcv._tab.Bytes = buf\n";
+    code += "\trcv._tab.Pos = i\n";
+    code += "}\n\n";
+  }
+
+  // Implement the table accessor
+  void GenTableAccessor(const StructDef &struct_def, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    GenReceiver(struct_def, code_ptr);
+    code += " Table() flatbuffers.Table ";
+    code += "{\n";
+
+    if (struct_def.fixed) {
+      code += "\treturn rcv._tab.Table\n";
+    } else {
+      code += "\treturn rcv._tab\n";
+    }
+    code += "}\n\n";
+  }
+
+  // Get the length of a vector.
+  void GetVectorLen(const StructDef &struct_def, const FieldDef &field,
+                    std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    GenReceiver(struct_def, code_ptr);
+    code += " " + MakeCamel(field.name) + "Length(";
+    code += ") int " + OffsetPrefix(field);
+    code += "\t\treturn rcv._tab.VectorLen(o)\n\t}\n";
+    code += "\treturn 0\n}\n\n";
+  }
+
+  // Get a [ubyte] vector as a byte slice.
+  void GetUByteSlice(const StructDef &struct_def, const FieldDef &field,
+                     std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    GenReceiver(struct_def, code_ptr);
+    code += " " + MakeCamel(field.name) + "Bytes(";
+    code += ") []byte " + OffsetPrefix(field);
+    code += "\t\treturn rcv._tab.ByteVector(o + rcv._tab.Pos)\n\t}\n";
+    code += "\treturn nil\n}\n\n";
+  }
+
+  // Get the value of a struct's scalar.
+  void GetScalarFieldOfStruct(const StructDef &struct_def,
+                              const FieldDef &field,
+                              std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    std::string getter = GenGetter(field.value.type);
+    GenReceiver(struct_def, code_ptr);
+    code += " " + MakeCamel(field.name);
+    code += "() " + TypeName(field) + " {\n";
+    code += "\treturn " + CastToEnum(
+        field.value.type,
+        getter + "(rcv._tab.Pos + flatbuffers.UOffsetT(" +
+        NumToString(field.value.offset) + "))");
+    code += "\n}\n";
+  }
+
+  // Get the value of a table's scalar.
+  void GetScalarFieldOfTable(const StructDef &struct_def,
+                             const FieldDef &field,
+                             std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    std::string getter = GenGetter(field.value.type);
+    GenReceiver(struct_def, code_ptr);
+    code += " " + MakeCamel(field.name);
+    code += "() " + TypeName(field) + " ";
+    code += OffsetPrefix(field) + "\t\treturn ";
+    code += CastToEnum(field.value.type, getter + "(o + rcv._tab.Pos)");
+    code += "\n\t}\n";
+    code += "\treturn " + GenConstant(field) + "\n";
+    code += "}\n\n";
+  }
+
+  // Get a struct by initializing an existing struct.
+  // Specific to Struct.
+  void GetStructFieldOfStruct(const StructDef &struct_def,
+                              const FieldDef &field,
+                              std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    GenReceiver(struct_def, code_ptr);
+    code += " " + MakeCamel(field.name);
+    code += "(obj *" + TypeName(field);
+    code += ") *" + TypeName(field);
+    code += " {\n";
+    code += "\tif obj == nil {\n";
+    code += "\t\tobj = new(" + TypeName(field) + ")\n";
+    code += "\t}\n";
+    code += "\tobj.Init(rcv._tab.Bytes, rcv._tab.Pos+";
+    code += NumToString(field.value.offset) + ")";
+    code += "\n\treturn obj\n";
+    code += "}\n";
+  }
+
+  // Get a struct by initializing an existing struct.
+  // Specific to Table.
+  void GetStructFieldOfTable(const StructDef &struct_def,
+                             const FieldDef &field,
+                             std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    GenReceiver(struct_def, code_ptr);
+    code += " " + MakeCamel(field.name);
+    code += "(obj *";
+    code += TypeName(field);
+    code += ") *" + TypeName(field) + " " + OffsetPrefix(field);
+    if (field.value.type.struct_def->fixed) {
+      code += "\t\tx := o + rcv._tab.Pos\n";
+    } else {
+      code += "\t\tx := rcv._tab.Indirect(o + rcv._tab.Pos)\n";
+    }
+    code += "\t\tif obj == nil {\n";
+    code += "\t\t\tobj = new(" + TypeName(field) + ")\n";
+    code += "\t\t}\n";
+    code += "\t\tobj.Init(rcv._tab.Bytes, x)\n";
+    code += "\t\treturn obj\n\t}\n\treturn nil\n";
+    code += "}\n\n";
+  }
+
+  // Get the value of a string.
+  void GetStringField(const StructDef &struct_def,
+                      const FieldDef &field,
+                      std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    GenReceiver(struct_def, code_ptr);
+    code += " " + MakeCamel(field.name);
+    code += "() " + TypeName(field) + " ";
+    code += OffsetPrefix(field) + "\t\treturn " + GenGetter(field.value.type);
+    code += "(o + rcv._tab.Pos)\n\t}\n\treturn nil\n";
+    code += "}\n\n";
+  }
+
+  // Get the value of a union from an object.
+  void GetUnionField(const StructDef &struct_def, const FieldDef &field,
+                     std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    GenReceiver(struct_def, code_ptr);
+    code += " " + MakeCamel(field.name) + "(";
+    code += "obj " + GenTypePointer(field.value.type) + ") bool ";
+    code += OffsetPrefix(field);
+    code += "\t\t" + GenGetter(field.value.type);
+    code += "(obj, o)\n\t\treturn true\n\t}\n";
+    code += "\treturn false\n";
+    code += "}\n\n";
+  }
+
+  // Get the value of a vector's struct member.
+  void GetMemberOfVectorOfStruct(const StructDef &struct_def,
+                                 const FieldDef &field,
+                                 std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    auto vectortype = field.value.type.VectorType();
+
+    GenReceiver(struct_def, code_ptr);
+    code += " " + MakeCamel(field.name);
+    code += "(obj *" + TypeName(field);
+    code += ", j int) bool " + OffsetPrefix(field);
+    code += "\t\tx := rcv._tab.Vector(o)\n";
+    code += "\t\tx += flatbuffers.UOffsetT(j) * ";
+    code += NumToString(InlineSize(vectortype)) + "\n";
+    if (!(vectortype.struct_def->fixed)) {
+      code += "\t\tx = rcv._tab.Indirect(x)\n";
+    }
+    code += "\t\tobj.Init(rcv._tab.Bytes, x)\n";
+    code += "\t\treturn true\n\t}\n";
+    code += "\treturn false\n";
+    code += "}\n\n";
+  }
+
+  // Get the value of a vector's non-struct member.
+  void GetMemberOfVectorOfNonStruct(const StructDef &struct_def,
+                                    const FieldDef &field,
+                                    std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    auto vectortype = field.value.type.VectorType();
+
+    GenReceiver(struct_def, code_ptr);
+    code += " " + MakeCamel(field.name);
+    code += "(j int) " + TypeName(field) + " ";
+    code += OffsetPrefix(field);
+    code += "\t\ta := rcv._tab.Vector(o)\n";
+    code += "\t\treturn " + CastToEnum(
+        field.value.type,
+        GenGetter(field.value.type) + "(a + flatbuffers.UOffsetT(j*" +
+        NumToString(InlineSize(vectortype)) + "))");
+    code += "\n\t}\n";
+    if (vectortype.base_type == BASE_TYPE_STRING) {
+      code += "\treturn nil\n";
+    } else if (vectortype.base_type == BASE_TYPE_BOOL) {
+      code += "\treturn false\n";
+    } else {
+      code += "\treturn 0\n";
+    }
+    code += "}\n\n";
+  }
+
+  // Begin the creator function signature.
+  void BeginBuilderArgs(const StructDef &struct_def, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    if (code.substr(code.length() - 2) != "\n\n") {
+      // a previous mutate has not put an extra new line
+      code += "\n";
+    }
+    code += "func Create" + struct_def.name;
+    code += "(builder *flatbuffers.Builder";
+  }
+
+  // Recursively generate arguments for a constructor, to deal with nested
+  // structs.
+  void StructBuilderArgs(const StructDef &struct_def, const char *nameprefix,
+                         std::string *code_ptr) {
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (IsStruct(field.value.type)) {
+        // Generate arguments for a struct inside a struct. To ensure names
+        // don't clash, and to make it obvious these arguments are constructing
+        // a nested struct, prefix the name with the field name.
+        StructBuilderArgs(*field.value.type.struct_def,
+                          (nameprefix + (field.name + "_")).c_str(), code_ptr);
+      } else {
+        std::string &code = *code_ptr;
+        code += std::string(", ") + nameprefix;
+        code += GoIdentity(field.name);
+        code += " " + TypeName(field);
+      }
+    }
+  }
+
+  // End the creator function signature.
+  void EndBuilderArgs(std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += ") flatbuffers.UOffsetT {\n";
+  }
+
+  // Recursively generate struct construction statements and instert manual
+  // padding.
+  void StructBuilderBody(const StructDef &struct_def,
+                         const char *nameprefix, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "\tbuilder.Prep(" + NumToString(struct_def.minalign) + ", ";
+    code += NumToString(struct_def.bytesize) + ")\n";
+    for (auto it = struct_def.fields.vec.rbegin();
+         it != struct_def.fields.vec.rend(); ++it) {
+      auto &field = **it;
+      if (field.padding)
+        code += "\tbuilder.Pad(" + NumToString(field.padding) + ")\n";
+      if (IsStruct(field.value.type)) {
+        StructBuilderBody(*field.value.type.struct_def,
+                          (nameprefix + (field.name + "_")).c_str(), code_ptr);
+      } else {
+        code += "\tbuilder.Prepend" + GenMethod(field) + "(";
+        code += CastToBaseType(field.value.type, nameprefix + GoIdentity(field.name)) + ")\n";
+      }
+    }
+  }
+
+  void EndBuilderBody(std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "\treturn builder.Offset()\n";
+    code += "}\n";
+  }
+
+  // Get the value of a table's starting offset.
+  void GetStartOfTable(const StructDef &struct_def, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "func " + struct_def.name + "Start";
+    code += "(builder *flatbuffers.Builder) {\n";
+    code += "\tbuilder.StartObject(";
+    code += NumToString(struct_def.fields.vec.size());
+    code += ")\n}\n";
+  }
+
+  // Set the value of a table's field.
+  void BuildFieldOfTable(const StructDef &struct_def, const FieldDef &field,
+                         const size_t offset, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "func " + struct_def.name + "Add" + MakeCamel(field.name);
+    code += "(builder *flatbuffers.Builder, ";
+    code += GoIdentity(field.name) + " ";
+    if (!IsScalar(field.value.type.base_type) && (!struct_def.fixed)) {
+      code += "flatbuffers.UOffsetT";
+    } else {
+      code += TypeName(field);
+    }
+    code += ") {\n";
+    code += "\tbuilder.Prepend";
+    code += GenMethod(field) + "Slot(";
+    code += NumToString(offset) + ", ";
+    if (!IsScalar(field.value.type.base_type) && (!struct_def.fixed)) {
+      code += "flatbuffers.UOffsetT";
+      code += "(";
+      code += GoIdentity(field.name) + ")";
+    } else {
+      code += CastToBaseType(field.value.type, GoIdentity(field.name));
+    }
+    code += ", " + GenConstant(field);
+    code += ")\n}\n";
+  }
+
+  // Set the value of one of the members of a table's vector.
+  void BuildVectorOfTable(const StructDef &struct_def,
+                          const FieldDef &field, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "func " + struct_def.name + "Start";
+    code += MakeCamel(field.name);
+    code += "Vector(builder *flatbuffers.Builder, numElems int) ";
+    code += "flatbuffers.UOffsetT {\n\treturn builder.StartVector(";
+    auto vector_type = field.value.type.VectorType();
+    auto alignment = InlineAlignment(vector_type);
+    auto elem_size = InlineSize(vector_type);
+    code += NumToString(elem_size);
+    code += ", numElems, " + NumToString(alignment);
+    code += ")\n}\n";
+  }
+
+  // Get the offset of the end of a table.
+  void GetEndOffsetOnTable(const StructDef &struct_def, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "func " + struct_def.name + "End";
+    code += "(builder *flatbuffers.Builder) flatbuffers.UOffsetT ";
+    code += "{\n\treturn builder.EndObject()\n}\n";
+  }
+
+  // Generate the receiver for function signatures.
+  void GenReceiver(const StructDef &struct_def, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "func (rcv *" + struct_def.name + ")";
+  }
+
+  // Generate a struct field getter, conditioned on its child type(s).
+  void GenStructAccessor(const StructDef &struct_def,
+                         const FieldDef &field, std::string *code_ptr) {
+    GenComment(field.doc_comment, code_ptr, nullptr, "");
+    if (IsScalar(field.value.type.base_type)) {
+      if (struct_def.fixed) {
+        GetScalarFieldOfStruct(struct_def, field, code_ptr);
+      } else {
+        GetScalarFieldOfTable(struct_def, field, code_ptr);
+      }
+    } else {
+      switch (field.value.type.base_type) {
+        case BASE_TYPE_STRUCT:
+          if (struct_def.fixed) {
+            GetStructFieldOfStruct(struct_def, field, code_ptr);
+          } else {
+            GetStructFieldOfTable(struct_def, field, code_ptr);
+          }
+          break;
+        case BASE_TYPE_STRING: GetStringField(struct_def, field, code_ptr); break;
+        case BASE_TYPE_VECTOR: {
+          auto vectortype = field.value.type.VectorType();
+          if (vectortype.base_type == BASE_TYPE_STRUCT) {
+            GetMemberOfVectorOfStruct(struct_def, field, code_ptr);
+          } else {
+            GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr);
+          }
+          break;
+        }
+        case BASE_TYPE_UNION: GetUnionField(struct_def, field, code_ptr); break;
+        default: FLATBUFFERS_ASSERT(0);
+      }
+    }
+    if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+      GetVectorLen(struct_def, field, code_ptr);
+      if (field.value.type.element == BASE_TYPE_UCHAR) {
+        GetUByteSlice(struct_def, field, code_ptr);
+      }
+    }
+  }
+
+  // Mutate the value of a struct's scalar.
+  void MutateScalarFieldOfStruct(const StructDef &struct_def,
+                                 const FieldDef &field,
+                                 std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    std::string type = MakeCamel(GenTypeBasic(field.value.type));
+    std::string setter = "rcv._tab.Mutate" + type;
+    GenReceiver(struct_def, code_ptr);
+    code += " Mutate" + MakeCamel(field.name);
+    code += "(n " + TypeName(field) + ") bool {\n\treturn " + setter;
+    code += "(rcv._tab.Pos+flatbuffers.UOffsetT(";
+    code += NumToString(field.value.offset) + "), ";
+    code += CastToBaseType(field.value.type, "n") + ")\n}\n\n";
+  }
+
+  // Mutate the value of a table's scalar.
+  void MutateScalarFieldOfTable(const StructDef &struct_def,
+                                const FieldDef &field,
+                                std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    std::string type = MakeCamel(GenTypeBasic(field.value.type));
+    std::string setter = "rcv._tab.Mutate" + type + "Slot";
+    GenReceiver(struct_def, code_ptr);
+    code += " Mutate" + MakeCamel(field.name);
+    code += "(n " + TypeName(field) + ") bool {\n\treturn ";
+    code += setter + "(" + NumToString(field.value.offset) + ", ";
+    code += CastToBaseType(field.value.type, "n") + ")\n";
+    code += "}\n\n";
+  }
+
+  // Mutate an element of a vector of scalars.
+  void MutateElementOfVectorOfNonStruct(const StructDef &struct_def,
+                                        const FieldDef &field,
+                                        std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    auto vectortype = field.value.type.VectorType();
+    std::string type = MakeCamel(GenTypeBasic(vectortype));
+    std::string setter = "rcv._tab.Mutate" + type;
+    GenReceiver(struct_def, code_ptr);
+    code += " Mutate" + MakeCamel(field.name);
+    code += "(j int, n " + TypeName(field) + ") bool ";
+    code += OffsetPrefix(field);
+    code += "\t\ta := rcv._tab.Vector(o)\n";
+    code += "\t\treturn " + setter + "(";
+    code += "a+flatbuffers.UOffsetT(j*";
+    code += NumToString(InlineSize(vectortype)) + "), ";
+    code += CastToBaseType(vectortype, "n") + ")\n";
+    code += "\t}\n";
+    code += "\treturn false\n";
+    code += "}\n\n";
+  }
+
+  // Generate a struct field setter, conditioned on its child type(s).
+  void GenStructMutator(const StructDef &struct_def, const FieldDef &field,
+                        std::string *code_ptr) {
+    GenComment(field.doc_comment, code_ptr, nullptr, "");
+    if (IsScalar(field.value.type.base_type)) {
+      if (struct_def.fixed) {
+        MutateScalarFieldOfStruct(struct_def, field, code_ptr);
+      } else {
+        MutateScalarFieldOfTable(struct_def, field, code_ptr);
+      }
+    } else if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+      if (IsScalar(field.value.type.element)) {
+        MutateElementOfVectorOfNonStruct(struct_def, field, code_ptr);
+      }
+    }
+  }
+
+  // Generate table constructors, conditioned on its members' types.
+  void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) {
+    GetStartOfTable(struct_def, code_ptr);
+
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+
+      auto offset = it - struct_def.fields.vec.begin();
+      BuildFieldOfTable(struct_def, field, offset, code_ptr);
+      if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+        BuildVectorOfTable(struct_def, field, code_ptr);
+      }
+    }
+
+    GetEndOffsetOnTable(struct_def, code_ptr);
+  }
+
+  // Generate struct or table methods.
+  void GenStruct(const StructDef &struct_def, std::string *code_ptr) {
+    if (struct_def.generated) return;
+
+    cur_name_space_ = struct_def.defined_namespace;
+
+    GenComment(struct_def.doc_comment, code_ptr, nullptr);
+    BeginClass(struct_def, code_ptr);
+    if (!struct_def.fixed) {
+      // Generate a special accessor for the table that has been declared as
+      // the root type.
+      NewRootTypeFromBuffer(struct_def, code_ptr);
+    }
+    // Generate the Init method that sets the field in a pre-existing
+    // accessor object. This is to allow object reuse.
+    InitializeExisting(struct_def, code_ptr);
+    // Generate _tab accessor
+    GenTableAccessor(struct_def, code_ptr);
+
+    // Generate struct fields accessors
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+
+      GenStructAccessor(struct_def, field, code_ptr);
+      GenStructMutator(struct_def, field, code_ptr);
+    }
+
+    // Generate builders
+    if (struct_def.fixed) {
+      // create a struct constructor function
+      GenStructBuilder(struct_def, code_ptr);
+    } else {
+      // Create a set of functions that allow table construction.
+      GenTableBuilders(struct_def, code_ptr);
+    }
+  }
+
+  // Generate enum declarations.
+  void GenEnum(const EnumDef &enum_def, std::string *code_ptr) {
+    if (enum_def.generated) return;
+
+    auto max_name_length = MaxNameLength(enum_def);
+    cur_name_space_ = enum_def.defined_namespace;
+
+    GenComment(enum_def.doc_comment, code_ptr, nullptr);
+    GenEnumType(enum_def, code_ptr);
+    BeginEnum(code_ptr);
+    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, max_name_length, code_ptr);
+    }
+    EndEnum(code_ptr);
+
+    BeginEnumNames(enum_def, code_ptr);
+    for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
+      auto &ev = **it;
+      EnumNameMember(enum_def, ev, max_name_length, code_ptr);
+    }
+    EndEnumNames(code_ptr);
+
+    BeginEnumValues(enum_def, code_ptr);
+    for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
+         ++it) {
+      auto &ev = **it;
+      EnumValueMember(enum_def, ev, max_name_length, code_ptr);
+    }
+    EndEnumValues(code_ptr);
+
+    EnumStringer(enum_def, code_ptr);
+  }
+
+  // Returns the function name that is able to read a value of the given type.
+  std::string GenGetter(const Type &type) {
+    switch (type.base_type) {
+      case BASE_TYPE_STRING: return "rcv._tab.ByteVector";
+      case BASE_TYPE_UNION: return "rcv._tab.Union";
+      case BASE_TYPE_VECTOR: return GenGetter(type.VectorType());
+      default: return "rcv._tab.Get" + MakeCamel(GenTypeBasic(type));
+    }
+  }
+
+  // Returns the method name for use with add/put calls.
+  std::string GenMethod(const FieldDef &field) {
+    return IsScalar(field.value.type.base_type)
+               ? MakeCamel(GenTypeBasic(field.value.type))
+               : (IsStruct(field.value.type) ? "Struct" : "UOffsetT");
+  }
+
+  std::string GenTypeBasic(const Type &type) {
+    static const char *ctypename[] = {
+    // clang-format off
+      #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+        CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
+        #GTYPE,
+        FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+      #undef FLATBUFFERS_TD
+      // clang-format on
+    };
+    return ctypename[type.base_type];
+  }
+
+  std::string GenTypePointer(const Type &type) {
+    switch (type.base_type) {
+      case BASE_TYPE_STRING: return "[]byte";
+      case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType());
+      case BASE_TYPE_STRUCT: return WrapInNameSpaceAndTrack(*type.struct_def);
+      case BASE_TYPE_UNION:
+        // fall through
+      default: return "*flatbuffers.Table";
+    }
+  }
+
+  std::string GenTypeGet(const Type &type) {
+    if (type.enum_def != nullptr) {
+      return GetEnumTypeName(*type.enum_def);
+    }
+    return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type);
+  }
+
+  std::string TypeName(const FieldDef &field) {
+    return GenTypeGet(field.value.type);
+  }
+
+  // If type is an enum, returns value with a cast to the enum type, otherwise
+  // returns value as-is.
+  std::string CastToEnum(const Type &type, std::string value) {
+    if (type.enum_def == nullptr) {
+      return value;
+    } else {
+      return GenTypeGet(type) + "(" + value + ")";
+    }
+  }
+
+  // If type is an enum, returns value with a cast to the enum base type,
+  // otherwise returns value as-is.
+  std::string CastToBaseType(const Type &type, std::string value) {
+    if (type.enum_def == nullptr) {
+      return value;
+    } else {
+      return GenTypeBasic(type) + "(" + value + ")";
+    }
+  }
+
+  std::string GenConstant(const FieldDef &field) {
+    switch (field.value.type.base_type) {
+      case BASE_TYPE_BOOL: return field.value.constant == "0" ? "false" : "true";;
+      default: return field.value.constant;
+    }
+  }
+
+  // Create a struct with a builder and the struct's arguments.
+  void GenStructBuilder(const StructDef &struct_def, std::string *code_ptr) {
+    BeginBuilderArgs(struct_def, code_ptr);
+    StructBuilderArgs(struct_def, "", code_ptr);
+    EndBuilderArgs(code_ptr);
+
+    StructBuilderBody(struct_def, "", code_ptr);
+    EndBuilderBody(code_ptr);
+  }
+  // Begin by declaring namespace and imports.
+  void BeginFile(const std::string &name_space_name, const bool needs_imports,
+                 const bool is_enum, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code = code + "// Code generated by the FlatBuffers compiler. DO NOT EDIT.\n\n";
+    code += "package " + name_space_name + "\n\n";
+    if (needs_imports) {
+      code += "import (\n";
+      if (is_enum) {
+        code += "\t\"strconv\"\n\n";
+      }
+      if (!parser_.opts.go_import.empty()) {
+        code += "\tflatbuffers \"" + parser_.opts.go_import + "\"\n";
+      } else {
+        code += "\tflatbuffers \"github.com/google/flatbuffers/go\"\n";
+      }
+      if (tracked_imported_namespaces_.size() > 0) {
+        code += "\n";
+        for (auto it = tracked_imported_namespaces_.begin();
+             it != tracked_imported_namespaces_.end();
+             ++it) {
+        code += "\t" + NamespaceImportName(*it) + " \"" + \
+                NamespaceImportPath(*it) + "\"\n";
+        }
+      }
+      code += ")\n\n";
+    } else {
+      if (is_enum) {
+        code += "import \"strconv\"\n\n";
+      }
+    }
+  }
+
+  // Save out the generated code for a Go Table type.
+  bool SaveType(const Definition &def, const std::string &classcode,
+                const bool needs_imports, const bool is_enum) {
+    if (!classcode.length()) return true;
+
+    Namespace &ns = go_namespace_.components.empty() ? *def.defined_namespace
+                                                     : go_namespace_;
+    std::string code = "";
+    BeginFile(LastNamespacePart(ns), needs_imports, is_enum, &code);
+    code += classcode;
+    // Strip extra newlines at end of file to make it gofmt-clean.
+    while (code.length() > 2 && code.substr(code.length() - 2) == "\n\n") {
+      code.pop_back();
+    }
+    std::string filename = NamespaceDir(ns) + def.name + ".go";
+    return SaveFile(filename.c_str(), code, false);
+  }
+
+  // Create the full name of the imported namespace (format: A__B__C).
+  std::string NamespaceImportName(const Namespace *ns) {
+    std::string s = "";
+    for (auto it = ns->components.begin(); it != ns->components.end(); ++it) {
+      if (s.size() == 0) {
+        s += *it;
+      } else {
+        s += "__" + *it;
+      }
+    }
+    return s;
+  }
+
+  // Create the full path for the imported namespace (format: A/B/C).
+  std::string NamespaceImportPath(const Namespace *ns) {
+    std::string s = "";
+    for (auto it = ns->components.begin(); it != ns->components.end(); ++it) {
+      if (s.size() == 0) {
+        s += *it;
+      } else {
+        s += "/" + *it;
+      }
+    }
+    return s;
+  }
+
+  // Ensure that a type is prefixed with its go package import name if it is
+  // used outside of its namespace.
+  std::string WrapInNameSpaceAndTrack(const Namespace *ns,
+                                      const std::string &name) {
+    if (CurrentNameSpace() == ns) return name;
+
+    tracked_imported_namespaces_.insert(ns);
+
+    std::string import_name = NamespaceImportName(ns);
+    return import_name + "." + name;
+  }
+
+  std::string WrapInNameSpaceAndTrack(const Definition &def) {
+    return WrapInNameSpaceAndTrack(def.defined_namespace, def.name);
+  }
+
+  const Namespace *CurrentNameSpace() const { return cur_name_space_; }
+
+  static size_t MaxNameLength(const EnumDef &enum_def) {
+    size_t max = 0;
+    for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
+        ++it) {
+      max = std::max((*it)->name.length(), max);
+    }
+    return max;
+  }
+};
+}  // namespace go
+
+bool GenerateGo(const Parser &parser, const std::string &path,
+                const std::string &file_name) {
+  go::GoGenerator generator(parser, path, file_name, parser.opts.go_namespace);
+  return generator.generate();
+}
+
+}  // namespace flatbuffers
diff --git a/src/idl_gen_grpc.cpp b/src/idl_gen_grpc.cpp
new file mode 100644
index 0000000..1d5e8e5
--- /dev/null
+++ b/src/idl_gen_grpc.cpp
@@ -0,0 +1,371 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// independent from idl_parser, since this code is not needed for most clients
+
+#include "flatbuffers/code_generators.h"
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+#include "src/compiler/cpp_generator.h"
+#include "src/compiler/go_generator.h"
+#include "src/compiler/java_generator.h"
+
+#if defined(_MSC_VER)
+#  pragma warning(push)
+#  pragma warning(disable : 4512)  // C4512: 'class' : assignment operator could
+// not be generated
+#endif
+
+namespace flatbuffers {
+
+class FlatBufMethod : public grpc_generator::Method {
+ public:
+  enum Streaming {
+    kNone, kClient, kServer, kBiDi
+  };
+
+  FlatBufMethod(const RPCCall *method) : method_(method) {
+    streaming_ = kNone;
+    auto val = method_->attributes.Lookup("streaming");
+    if (val) {
+      if (val->constant == "client") streaming_ = kClient;
+      if (val->constant == "server") streaming_ = kServer;
+      if (val->constant == "bidi") streaming_ = kBiDi;
+    }
+  }
+
+  grpc::string GetLeadingComments(const grpc::string) const { return ""; }
+
+  grpc::string GetTrailingComments(const grpc::string) const { return ""; }
+
+  std::vector<grpc::string> GetAllComments() const {
+    return method_->doc_comment;
+  }
+
+  std::string name() const { return method_->name; }
+
+  std::string GRPCType(const StructDef &sd) const {
+    return "flatbuffers::grpc::Message<" + sd.name + ">";
+  }
+
+  std::string get_input_type_name() const { return (*method_->request).name; }
+
+  std::string get_output_type_name() const { return (*method_->response).name; }
+
+  bool get_module_and_message_path_input(grpc::string * /*str*/,
+                                         grpc::string /*generator_file_name*/,
+                                         bool /*generate_in_pb2_grpc*/,
+                                         grpc::string /*import_prefix*/) const {
+    return true;
+  }
+
+  bool get_module_and_message_path_output(
+      grpc::string * /*str*/, grpc::string /*generator_file_name*/,
+      bool /*generate_in_pb2_grpc*/, grpc::string /*import_prefix*/) const {
+    return true;
+  }
+
+  std::string input_type_name() const { return GRPCType(*method_->request); }
+
+  std::string output_type_name() const { return GRPCType(*method_->response); }
+
+  bool NoStreaming() const { return streaming_ == kNone; }
+
+  bool ClientStreaming() const { return streaming_ == kClient; }
+
+  bool ServerStreaming() const { return streaming_ == kServer; }
+
+  bool BidiStreaming() const { return streaming_ == kBiDi; }
+
+ private:
+  const RPCCall *method_;
+  Streaming streaming_;
+};
+
+class FlatBufService : public grpc_generator::Service {
+ public:
+  FlatBufService(const ServiceDef *service) : service_(service) {}
+
+  grpc::string GetLeadingComments(const grpc::string) const { return ""; }
+
+  grpc::string GetTrailingComments(const grpc::string) const { return ""; }
+
+  std::vector<grpc::string> GetAllComments() const {
+    return service_->doc_comment;
+  }
+
+  std::string name() const { return service_->name; }
+
+  int method_count() const {
+    return static_cast<int>(service_->calls.vec.size());
+  }
+
+  std::unique_ptr<const grpc_generator::Method> method(int i) const {
+    return std::unique_ptr<const grpc_generator::Method>(
+        new FlatBufMethod(service_->calls.vec[i]));
+  }
+
+ private:
+  const ServiceDef *service_;
+};
+
+class FlatBufPrinter : public grpc_generator::Printer {
+ public:
+  FlatBufPrinter(std::string *str) : str_(str), escape_char_('$'), indent_(0) {}
+
+  void Print(const std::map<std::string, std::string> &vars,
+             const char *string_template) {
+    std::string s = string_template;
+    // Replace any occurrences of strings in "vars" that are surrounded
+    // by the escape character by what they're mapped to.
+    size_t pos;
+    while ((pos = s.find(escape_char_)) != std::string::npos) {
+      // Found an escape char, must also find the closing one.
+      size_t pos2 = s.find(escape_char_, pos + 1);
+      // If placeholder not closed, ignore.
+      if (pos2 == std::string::npos) break;
+      auto it = vars.find(s.substr(pos + 1, pos2 - pos - 1));
+      // If unknown placeholder, ignore.
+      if (it == vars.end()) break;
+      // Subtitute placeholder.
+      s.replace(pos, pos2 - pos + 1, it->second);
+    }
+    Print(s.c_str());
+  }
+
+  void Print(const char *s) {
+    if (s == nullptr || *s == '\0') { return; }
+    // Add this string, but for each part separated by \n, add indentation.
+    for (;;) {
+      // Current indentation.
+      str_->insert(str_->end(), indent_ * 2, ' ');
+      // See if this contains more than one line.
+      const char *lf = strchr(s, '\n');
+      if (lf) {
+        (*str_) += std::string(s, lf + 1);
+        s = lf + 1;
+        if (!*s) break;  // Only continue if there's more lines.
+      } else {
+        (*str_) += s;
+        break;
+      }
+    }
+  }
+
+  void Indent() { indent_++; }
+
+  void Outdent() {
+    indent_--;
+        FLATBUFFERS_ASSERT(indent_ >= 0);
+  }
+
+ private:
+  std::string *str_;
+  char escape_char_;
+  int indent_;
+};
+
+class FlatBufFile : public grpc_generator::File {
+ public:
+  enum Language {
+    kLanguageGo, kLanguageCpp, kLanguageJava
+  };
+
+  FlatBufFile(const Parser &parser, const std::string &file_name,
+              Language language)
+      : parser_(parser), file_name_(file_name), language_(language) {}
+
+  FlatBufFile &operator=(const FlatBufFile &);
+
+  grpc::string GetLeadingComments(const grpc::string) const { return ""; }
+
+  grpc::string GetTrailingComments(const grpc::string) const { return ""; }
+
+  std::vector<grpc::string> GetAllComments() const {
+    return std::vector<grpc::string>();
+  }
+
+  std::string filename() const { return file_name_; }
+
+  std::string filename_without_ext() const {
+    return StripExtension(file_name_);
+  }
+
+  std::string message_header_ext() const { return "_generated.h"; }
+
+  std::string service_header_ext() const { return ".grpc.fb.h"; }
+
+  std::string package() const {
+    return parser_.current_namespace_->GetFullyQualifiedName("");
+  }
+
+  std::vector<std::string> package_parts() const {
+    return parser_.current_namespace_->components;
+  }
+
+  std::string additional_headers() const {
+    switch (language_) {
+      case kLanguageCpp: {
+        return "#include \"flatbuffers/grpc.h\"\n";
+      }
+      case kLanguageGo: {
+        return "import \"github.com/google/flatbuffers/go\"";
+      }
+      case kLanguageJava: {
+        return "import com.google.flatbuffers.grpc.FlatbuffersUtils;";
+      }
+    }
+    return "";
+  }
+
+  int service_count() const {
+    return static_cast<int>(parser_.services_.vec.size());
+  }
+
+  std::unique_ptr<const grpc_generator::Service> service(int i) const {
+    return std::unique_ptr<const grpc_generator::Service>(
+        new FlatBufService(parser_.services_.vec[i]));
+  }
+
+  std::unique_ptr<grpc_generator::Printer> CreatePrinter(
+      std::string *str) const {
+    return std::unique_ptr<grpc_generator::Printer>(new FlatBufPrinter(str));
+  }
+
+ private:
+  const Parser &parser_;
+  const std::string &file_name_;
+  const Language language_;
+};
+
+class GoGRPCGenerator : public flatbuffers::BaseGenerator {
+ public:
+  GoGRPCGenerator(const Parser &parser, const std::string &path,
+                  const std::string &file_name)
+      : BaseGenerator(parser, path, file_name, "", "" /*Unused*/),
+        parser_(parser),
+        path_(path),
+        file_name_(file_name) {}
+
+  bool generate() {
+    FlatBufFile file(parser_, file_name_, FlatBufFile::kLanguageGo);
+    grpc_go_generator::Parameters p;
+    p.custom_method_io_type = "flatbuffers.Builder";
+    for (int i = 0; i < file.service_count(); i++) {
+      auto service = file.service(i);
+      const Definition *def = parser_.services_.vec[i];
+      p.package_name = LastNamespacePart(*(def->defined_namespace));
+      p.service_prefix = def->defined_namespace->GetFullyQualifiedName(""); // file.package();
+      std::string output =
+          grpc_go_generator::GenerateServiceSource(&file, service.get(), &p);
+      std::string filename =
+          NamespaceDir(*def->defined_namespace) + def->name + "_grpc.go";
+      if (!flatbuffers::SaveFile(filename.c_str(), output, false)) return false;
+    }
+    return true;
+  }
+
+ protected:
+  const Parser &parser_;
+  const std::string &path_, &file_name_;
+};
+
+bool GenerateGoGRPC(const Parser &parser, const std::string &path,
+                    const std::string &file_name) {
+  int nservices = 0;
+  for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
+       ++it) {
+    if (!(*it)->generated) nservices++;
+  }
+  if (!nservices) return true;
+  return GoGRPCGenerator(parser, path, file_name).generate();
+}
+
+bool GenerateCppGRPC(const Parser &parser, const std::string &path,
+                     const std::string &file_name) {
+  int nservices = 0;
+  for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
+       ++it) {
+    if (!(*it)->generated) nservices++;
+  }
+  if (!nservices) return true;
+
+  grpc_cpp_generator::Parameters generator_parameters;
+  // TODO(wvo): make the other parameters in this struct configurable.
+  generator_parameters.use_system_headers = true;
+
+  FlatBufFile fbfile(parser, file_name, FlatBufFile::kLanguageCpp);
+
+  std::string header_code =
+      grpc_cpp_generator::GetHeaderPrologue(&fbfile, generator_parameters) +
+          grpc_cpp_generator::GetHeaderIncludes(&fbfile, generator_parameters) +
+          grpc_cpp_generator::GetHeaderServices(&fbfile, generator_parameters) +
+          grpc_cpp_generator::GetHeaderEpilogue(&fbfile, generator_parameters);
+
+  std::string source_code =
+      grpc_cpp_generator::GetSourcePrologue(&fbfile, generator_parameters) +
+          grpc_cpp_generator::GetSourceIncludes(&fbfile, generator_parameters) +
+          grpc_cpp_generator::GetSourceServices(&fbfile, generator_parameters) +
+          grpc_cpp_generator::GetSourceEpilogue(&fbfile, generator_parameters);
+
+  return flatbuffers::SaveFile((path + file_name + ".grpc.fb.h").c_str(),
+                               header_code, false) &&
+      flatbuffers::SaveFile((path + file_name + ".grpc.fb.cc").c_str(),
+                            source_code, false);
+}
+
+class JavaGRPCGenerator : public flatbuffers::BaseGenerator {
+ public:
+  JavaGRPCGenerator(const Parser &parser, const std::string &path,
+                    const std::string &file_name)
+      : BaseGenerator(parser, path, file_name, "", "." /*separator*/) {}
+
+  bool generate() {
+    FlatBufFile file(parser_, file_name_, FlatBufFile::kLanguageJava);
+    grpc_java_generator::Parameters p;
+    for (int i = 0; i < file.service_count(); i++) {
+      auto service = file.service(i);
+      const Definition *def = parser_.services_.vec[i];
+      p.package_name =
+          def->defined_namespace->GetFullyQualifiedName("");  // file.package();
+      std::string output =
+          grpc_java_generator::GenerateServiceSource(&file, service.get(), &p);
+      std::string filename =
+          NamespaceDir(*def->defined_namespace) + def->name + "Grpc.java";
+      if (!flatbuffers::SaveFile(filename.c_str(), output, false)) return false;
+    }
+    return true;
+  }
+};
+
+bool GenerateJavaGRPC(const Parser &parser, const std::string &path,
+                      const std::string &file_name) {
+  int nservices = 0;
+  for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
+       ++it) {
+    if (!(*it)->generated) nservices++;
+  }
+  if (!nservices) return true;
+  return JavaGRPCGenerator(parser, path, file_name).generate();
+}
+
+}  // namespace flatbuffers
+
+#if defined(_MSC_VER)
+#  pragma warning(pop)
+#endif
diff --git a/src/idl_gen_js_ts.cpp b/src/idl_gen_js_ts.cpp
new file mode 100644
index 0000000..9c89c1a
--- /dev/null
+++ b/src/idl_gen_js_ts.cpp
@@ -0,0 +1,1405 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// independent from idl_parser, since this code is not needed for most clients
+#include <cassert>
+#include <unordered_map>
+#include <unordered_set>
+
+#include "flatbuffers/code_generators.h"
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+namespace flatbuffers {
+
+const std::string kGeneratedFileNamePostfix = "_generated";
+
+struct JsTsLanguageParameters {
+  IDLOptions::Language language;
+  std::string file_extension;
+};
+
+struct ReexportDescription {
+  std::string symbol;
+  std::string source_namespace;
+  std::string target_namespace;
+};
+
+enum AnnotationType { kParam = 0, kType = 1, kReturns = 2 };
+
+const JsTsLanguageParameters &GetJsLangParams(IDLOptions::Language lang) {
+  static JsTsLanguageParameters js_language_parameters[] = {
+    {
+        IDLOptions::kJs,
+        ".js",
+    },
+    {
+        IDLOptions::kTs,
+        ".ts",
+    },
+  };
+
+  if (lang == IDLOptions::kJs) {
+    return js_language_parameters[0];
+  } else {
+    FLATBUFFERS_ASSERT(lang == IDLOptions::kTs);
+    return js_language_parameters[1];
+  }
+}
+
+static std::string GeneratedFileName(const std::string &path,
+                                     const std::string &file_name,
+                                     const JsTsLanguageParameters &lang) {
+  return path + file_name + kGeneratedFileNamePostfix + lang.file_extension;
+}
+
+namespace jsts {
+// Iterate through all definitions we haven't generate code for (enums, structs,
+// and tables) and output them to a single file.
+class JsTsGenerator : public BaseGenerator {
+ public:
+  typedef std::unordered_set<std::string> imported_fileset;
+  typedef std::unordered_multimap<std::string, ReexportDescription>
+      reexport_map;
+
+  JsTsGenerator(const Parser &parser, const std::string &path,
+                const std::string &file_name)
+      : BaseGenerator(parser, path, file_name, "", "."),
+        lang_(GetJsLangParams(parser_.opts.lang)) {}
+  // Iterate through all definitions we haven't generate code for (enums,
+  // structs, and tables) and output them to a single file.
+  bool generate() {
+    imported_fileset imported_files;
+    reexport_map reexports;
+
+    std::string enum_code, struct_code, import_code, exports_code, code;
+    generateEnums(&enum_code, &exports_code, reexports);
+    generateStructs(&struct_code, &exports_code, imported_files);
+    generateImportDependencies(&import_code, imported_files);
+    generateReexports(&import_code, reexports, imported_files);
+
+    code = code + "// " + FlatBuffersGeneratedWarning() + "\n\n";
+
+    // Generate code for all the namespace declarations.
+    GenNamespaces(&code, &exports_code);
+
+    // Output the main declaration code from above.
+    code += import_code;
+
+    code += enum_code;
+    code += struct_code;
+
+    if (lang_.language == IDLOptions::kJs && !exports_code.empty() &&
+        !parser_.opts.skip_js_exports) {
+      if (parser_.opts.use_ES6_js_export_format)
+        code += "// Exports for ECMAScript6 Modules\n";
+      else
+        code += "// Exports for Node.js and RequireJS\n";
+      code += exports_code;
+    }
+
+    return SaveFile(GeneratedFileName(path_, file_name_, lang_).c_str(), code,
+                    false);
+  }
+
+ private:
+  JsTsLanguageParameters lang_;
+
+  // Generate code for imports
+  void generateImportDependencies(std::string *code_ptr,
+                                  const imported_fileset &imported_files) {
+    std::string &code = *code_ptr;
+    for (auto it = imported_files.begin(); it != imported_files.end(); ++it) {
+      const auto &file = *it;
+      const auto basename =
+          flatbuffers::StripPath(flatbuffers::StripExtension(file));
+      if (basename != file_name_) {
+        code += GenPrefixedImport(file, basename);
+      }
+    }
+  }
+
+  // Generate reexports, which might not have been explicitly imported using the
+  // "export import" trick
+  void generateReexports(std::string *code_ptr, const reexport_map &reexports,
+                         imported_fileset imported_files) {
+    if (!parser_.opts.reexport_ts_modules ||
+        lang_.language != IDLOptions::kTs) {
+      return;
+    }
+
+    std::string &code = *code_ptr;
+    for (auto it = reexports.begin(); it != reexports.end(); ++it) {
+      const auto &file = *it;
+      const auto basename =
+          flatbuffers::StripPath(flatbuffers::StripExtension(file.first));
+      if (basename != file_name_) {
+        if (imported_files.find(file.first) == imported_files.end()) {
+          code += GenPrefixedImport(file.first, basename);
+          imported_files.emplace(file.first);
+        }
+
+        code += "export namespace " + file.second.target_namespace + " { \n";
+        code += "export import " + file.second.symbol + " = ";
+        code += GenFileNamespacePrefix(file.first) + "." +
+                file.second.source_namespace + "." + file.second.symbol +
+                "; }\n";
+      }
+    }
+  }
+
+  // Generate code for all enums.
+  void generateEnums(std::string *enum_code_ptr, std::string *exports_code_ptr,
+                     reexport_map &reexports) {
+    for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
+         ++it) {
+      auto &enum_def = **it;
+      GenEnum(enum_def, enum_code_ptr, exports_code_ptr, reexports, false);
+      GenEnum(enum_def, enum_code_ptr, exports_code_ptr, reexports, true);
+    }
+  }
+
+  // Generate code for all structs.
+  void generateStructs(std::string *decl_code_ptr,
+                       std::string *exports_code_ptr,
+                       imported_fileset &imported_files) {
+    for (auto it = parser_.structs_.vec.begin();
+         it != parser_.structs_.vec.end(); ++it) {
+      auto &struct_def = **it;
+      GenStruct(parser_, struct_def, decl_code_ptr, exports_code_ptr,
+                imported_files);
+    }
+  }
+  void GenNamespaces(std::string *code_ptr, std::string *exports_ptr) {
+    if (lang_.language == IDLOptions::kTs &&
+        parser_.opts.skip_flatbuffers_import) {
+      return;
+    }
+
+    std::set<std::string> namespaces;
+
+    for (auto it = parser_.namespaces_.begin(); it != parser_.namespaces_.end();
+         ++it) {
+      std::string namespace_so_far;
+
+      // Gather all parent namespaces for this namespace
+      for (auto component = (*it)->components.begin();
+           component != (*it)->components.end(); ++component) {
+        if (!namespace_so_far.empty()) { namespace_so_far += '.'; }
+        namespace_so_far += *component;
+        namespaces.insert(namespace_so_far);
+      }
+    }
+
+    // Make sure parent namespaces come before child namespaces
+    std::vector<std::string> sorted_namespaces(namespaces.begin(),
+                                               namespaces.end());
+    std::sort(sorted_namespaces.begin(), sorted_namespaces.end());
+
+    // Emit namespaces in a form that Closure Compiler can optimize
+    std::string &code = *code_ptr;
+    std::string &exports = *exports_ptr;
+    for (auto it = sorted_namespaces.begin(); it != sorted_namespaces.end();
+         ++it) {
+      if (lang_.language == IDLOptions::kTs) {
+        if (it->find('.') == std::string::npos) {
+          code += "import { flatbuffers } from \"./flatbuffers\"\n";
+          break;
+        }
+      } else {
+        code += "/**\n * @const\n * @namespace\n */\n";
+        if (it->find('.') == std::string::npos) {
+          code += "var ";
+          if (parser_.opts.use_goog_js_export_format) {
+            exports += "goog.exportSymbol('" + *it + "', " + *it + ");\n";
+          } else if (parser_.opts.use_ES6_js_export_format) {
+            exports += "export {" + *it + "};\n";
+          } else {
+            exports += "this." + *it + " = " + *it + ";\n";
+          }
+        }
+        code += *it + " = " + *it + " || {};\n\n";
+      }
+    }
+  }
+
+  // Generate a documentation comment, if available.
+  static void GenDocComment(const std::vector<std::string> &dc,
+                            std::string *code_ptr,
+                            const std::string &extra_lines,
+                            const char *indent = nullptr) {
+    if (dc.empty() && extra_lines.empty()) {
+      // Don't output empty comment blocks with 0 lines of comment content.
+      return;
+    }
+
+    std::string &code = *code_ptr;
+    if (indent) code += indent;
+    code += "/**\n";
+    for (auto it = dc.begin(); it != dc.end(); ++it) {
+      if (indent) code += indent;
+      code += " *" + *it + "\n";
+    }
+    if (!extra_lines.empty()) {
+      if (!dc.empty()) {
+        if (indent) code += indent;
+        code += " *\n";
+      }
+      if (indent) code += indent;
+      std::string::size_type start = 0;
+      for (;;) {
+        auto end = extra_lines.find('\n', start);
+        if (end != std::string::npos) {
+          code += " * " + extra_lines.substr(start, end - start) + "\n";
+          start = end + 1;
+        } else {
+          code += " * " + extra_lines.substr(start) + "\n";
+          break;
+        }
+      }
+    }
+    if (indent) code += indent;
+    code += " */\n";
+  }
+
+  static void GenDocComment(std::string *code_ptr,
+                            const std::string &extra_lines) {
+    GenDocComment(std::vector<std::string>(), code_ptr, extra_lines);
+  }
+
+  std::string GenTypeAnnotation(AnnotationType annotation_type,
+                                const std::string &type_name,
+                                const std::string &arg_name,
+                                bool include_newline = true) {
+    std::string result = "";
+    switch (annotation_type) {
+      case kParam: {
+        result += "@param";
+        break;
+      }
+      case kType: {
+        if (lang_.language != IDLOptions::kTs) {
+          result += "@type";
+        } else {
+          return "";
+        }
+        break;
+      }
+      case kReturns: {
+        result += "@returns";
+        break;
+      }
+    }
+    switch (lang_.language) {
+      case IDLOptions::kTs: {
+        result += " " + type_name;
+        break;
+      }
+      default: { result += " {" + type_name + "}"; }
+    }
+    if (!arg_name.empty()) {
+      result += " " + arg_name;
+    }
+    if (include_newline) {
+      result += "\n";
+    }
+
+    return result;
+  }
+
+  // Generate an enum declaration and an enum string lookup table.
+  void GenEnum(EnumDef &enum_def, std::string *code_ptr,
+               std::string *exports_ptr, reexport_map &reexports,
+               bool reverse) {
+    if (enum_def.generated) return;
+    if (reverse && lang_.language == IDLOptions::kTs) return;  // FIXME.
+    std::string &code = *code_ptr;
+    std::string &exports = *exports_ptr;
+    GenDocComment(enum_def.doc_comment, code_ptr,
+                  reverse ? "@enum {string}" : "@enum {number}");
+    std::string ns = GetNameSpace(enum_def);
+    std::string enum_def_name = enum_def.name + (reverse ? "Name" : "");
+    if (lang_.language == IDLOptions::kTs) {
+      if (!ns.empty()) { code += "export namespace " + ns + "{\n"; }
+      code += "export enum " + enum_def.name + "{\n";
+    } else {
+      if (enum_def.defined_namespace->components.empty()) {
+        code += "var ";
+        if (parser_.opts.use_goog_js_export_format) {
+          exports += "goog.exportSymbol('" + enum_def_name + "', " +
+                     enum_def.name + ");\n";
+        } else if (parser_.opts.use_ES6_js_export_format) {
+          exports += "export {" + enum_def_name + "};\n";
+        } else {
+          exports += "this." + enum_def_name + " = " + enum_def_name + ";\n";
+        }
+      }
+      code += WrapInNameSpace(enum_def) + (reverse ? "Name" : "") + " = {\n";
+    }
+    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().begin()) { code += '\n'; }
+        GenDocComment(ev.doc_comment, code_ptr, "", "  ");
+      }
+
+      // Generate mapping between EnumName: EnumValue(int)
+      if (reverse) {
+        code += "  " + enum_def.ToString(ev);
+        code += lang_.language == IDLOptions::kTs ? "= " : ": ";
+        code += "'" + ev.name + "'";
+      } else {
+        code += "  " + ev.name;
+        code += lang_.language == IDLOptions::kTs ? "= " : ": ";
+        code += enum_def.ToString(ev);
+      }
+
+      code += (it + 1) != enum_def.Vals().end() ? ",\n" : "\n";
+
+      if (ev.union_type.struct_def) {
+        ReexportDescription desc = { ev.name,
+                                     GetNameSpace(*ev.union_type.struct_def),
+                                     GetNameSpace(enum_def) };
+        reexports.insert(
+            std::make_pair(ev.union_type.struct_def->file, std::move(desc)));
+      }
+    }
+
+    if (lang_.language == IDLOptions::kTs && !ns.empty()) { code += "}"; }
+    code += "};\n\n";
+  }
+
+  static std::string GenType(const Type &type) {
+    switch (type.base_type) {
+      case BASE_TYPE_BOOL:
+      case BASE_TYPE_CHAR: return "Int8";
+      case BASE_TYPE_UTYPE:
+      case BASE_TYPE_UCHAR: return "Uint8";
+      case BASE_TYPE_SHORT: return "Int16";
+      case BASE_TYPE_USHORT: return "Uint16";
+      case BASE_TYPE_INT: return "Int32";
+      case BASE_TYPE_UINT: return "Uint32";
+      case BASE_TYPE_LONG: return "Int64";
+      case BASE_TYPE_ULONG: return "Uint64";
+      case BASE_TYPE_FLOAT: return "Float32";
+      case BASE_TYPE_DOUBLE: return "Float64";
+      case BASE_TYPE_STRING: return "String";
+      case BASE_TYPE_VECTOR: return GenType(type.VectorType());
+      case BASE_TYPE_STRUCT: return type.struct_def->name;
+      default: return "Table";
+    }
+  }
+
+  std::string GenGetter(const Type &type, const std::string &arguments) {
+    switch (type.base_type) {
+      case BASE_TYPE_STRING: return GenBBAccess() + ".__string" + arguments;
+      case BASE_TYPE_STRUCT: return GenBBAccess() + ".__struct" + arguments;
+      case BASE_TYPE_UNION: return GenBBAccess() + ".__union" + arguments;
+      case BASE_TYPE_VECTOR: return GenGetter(type.VectorType(), arguments);
+      default: {
+        auto getter =
+            GenBBAccess() + ".read" + MakeCamel(GenType(type)) + arguments;
+        if (type.base_type == BASE_TYPE_BOOL) { getter = "!!" + getter; }
+        if (type.enum_def) {
+          getter = "/** " +
+                   GenTypeAnnotation(kType, WrapInNameSpace(*type.enum_def), "",
+                                     false) +
+                   " */ (" + getter + ")";
+        }
+        return getter;
+      }
+    }
+  }
+
+  std::string GenBBAccess() {
+    return lang_.language == IDLOptions::kTs ? "this.bb!" : "this.bb";
+  }
+
+  std::string GenDefaultValue(const Value &value, const std::string &context) {
+    if (value.type.enum_def) {
+      if (auto val = value.type.enum_def->FindByValue(value.constant)) {
+        if (lang_.language == IDLOptions::kTs) {
+          return GenPrefixedTypeName(WrapInNameSpace(*value.type.enum_def),
+                                     value.type.enum_def->file) +
+                 "." + val->name;
+        } else {
+          return WrapInNameSpace(*value.type.enum_def) + "." + val->name;
+        }
+      } else {
+        return "/** " +
+               GenTypeAnnotation(kType, WrapInNameSpace(*value.type.enum_def),
+                                 "", false) +
+               "} */ (" + value.constant + ")";
+      }
+    }
+
+    switch (value.type.base_type) {
+      case BASE_TYPE_BOOL: return value.constant == "0" ? "false" : "true";
+
+      case BASE_TYPE_STRING: return "null";
+
+      case BASE_TYPE_LONG:
+      case BASE_TYPE_ULONG: {
+        int64_t constant = StringToInt(value.constant.c_str());
+        return context + ".createLong(" +
+               NumToString(static_cast<int32_t>(constant)) + ", " +
+               NumToString(static_cast<int32_t>(constant >> 32)) + ")";
+      }
+
+      default: return value.constant;
+    }
+  }
+
+  std::string GenTypeName(const Type &type, bool input,
+                          bool allowNull = false) {
+    if (!input) {
+      if (type.base_type == BASE_TYPE_STRING ||
+          type.base_type == BASE_TYPE_STRUCT) {
+        std::string name;
+        if (type.base_type == BASE_TYPE_STRING) {
+          name = "string|Uint8Array";
+        } else {
+          name = WrapInNameSpace(*type.struct_def);
+        }
+        return (allowNull) ? (name + "|null") : (name);
+      }
+    }
+
+    switch (type.base_type) {
+      case BASE_TYPE_BOOL: return "boolean";
+      case BASE_TYPE_LONG:
+      case BASE_TYPE_ULONG: return "flatbuffers.Long";
+      default:
+        if (IsScalar(type.base_type)) {
+          if (type.enum_def) { return WrapInNameSpace(*type.enum_def); }
+          return "number";
+        }
+        return "flatbuffers.Offset";
+    }
+  }
+
+  // Returns the method name for use with add/put calls.
+  static std::string GenWriteMethod(const Type &type) {
+    // Forward to signed versions since unsigned versions don't exist
+    switch (type.base_type) {
+      case BASE_TYPE_UTYPE:
+      case BASE_TYPE_UCHAR: return GenWriteMethod(Type(BASE_TYPE_CHAR));
+      case BASE_TYPE_USHORT: return GenWriteMethod(Type(BASE_TYPE_SHORT));
+      case BASE_TYPE_UINT: return GenWriteMethod(Type(BASE_TYPE_INT));
+      case BASE_TYPE_ULONG: return GenWriteMethod(Type(BASE_TYPE_LONG));
+      default: break;
+    }
+
+    return IsScalar(type.base_type) ? MakeCamel(GenType(type))
+                                    : (IsStruct(type) ? "Struct" : "Offset");
+  }
+
+  template<typename T> static std::string MaybeAdd(T value) {
+    return value != 0 ? " + " + NumToString(value) : "";
+  }
+
+  template<typename T> static std::string MaybeScale(T value) {
+    return value != 1 ? " * " + NumToString(value) : "";
+  }
+
+  static std::string GenFileNamespacePrefix(const std::string &file) {
+    return "NS" + std::to_string(HashFnv1a<uint64_t>(file.c_str()));
+  }
+
+  std::string GenPrefixedImport(const std::string &full_file_name,
+                                const std::string &base_name) {
+    // Either keep the include path as it was
+    // or use only the base_name + kGeneratedFileNamePostfix
+    std::string path;
+    if (parser_.opts.keep_include_path) {
+      auto it = parser_.included_files_.find(full_file_name);
+      FLATBUFFERS_ASSERT(it != parser_.included_files_.end());
+      path =
+          flatbuffers::StripExtension(it->second) + kGeneratedFileNamePostfix;
+    } else {
+      path = base_name + kGeneratedFileNamePostfix;
+    }
+
+    // Add the include prefix and make the path always relative
+    path = flatbuffers::ConCatPathFileName(parser_.opts.include_prefix, path);
+    path = std::string(".") + kPathSeparator + path;
+
+    return "import * as " + GenFileNamespacePrefix(full_file_name) +
+           " from \"" + path + "\";\n";
+  }
+
+  // Adds a source-dependent prefix, for of import * statements.
+  std::string GenPrefixedTypeName(const std::string &typeName,
+                                  const std::string &file) {
+    const auto basename =
+        flatbuffers::StripPath(flatbuffers::StripExtension(file));
+    if (basename == file_name_ || parser_.opts.generate_all) {
+      return typeName;
+    }
+    return GenFileNamespacePrefix(file) + "." + typeName;
+  }
+
+  void GenStructArgs(const StructDef &struct_def, std::string *annotations,
+                     std::string *arguments, const std::string &nameprefix) {
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (IsStruct(field.value.type)) {
+        // Generate arguments for a struct inside a struct. To ensure names
+        // don't clash, and to make it obvious these arguments are constructing
+        // a nested struct, prefix the name with the field name.
+        GenStructArgs(*field.value.type.struct_def, annotations, arguments,
+                      nameprefix + field.name + "_");
+      } else {
+        *annotations +=
+            GenTypeAnnotation(kParam, GenTypeName(field.value.type, true),
+                              nameprefix + field.name);
+        if (lang_.language == IDLOptions::kTs) {
+          *arguments += ", " + nameprefix + field.name + ": " +
+                        GenTypeName(field.value.type, true);
+        } else {
+          *arguments += ", " + nameprefix + field.name;
+        }
+      }
+    }
+  }
+
+  static void GenStructBody(const StructDef &struct_def, std::string *body,
+                            const std::string &nameprefix) {
+    *body += "  builder.prep(";
+    *body += NumToString(struct_def.minalign) + ", ";
+    *body += NumToString(struct_def.bytesize) + ");\n";
+
+    for (auto it = struct_def.fields.vec.rbegin();
+         it != struct_def.fields.vec.rend(); ++it) {
+      auto &field = **it;
+      if (field.padding) {
+        *body += "  builder.pad(" + NumToString(field.padding) + ");\n";
+      }
+      if (IsStruct(field.value.type)) {
+        // Generate arguments for a struct inside a struct. To ensure names
+        // don't clash, and to make it obvious these arguments are constructing
+        // a nested struct, prefix the name with the field name.
+        GenStructBody(*field.value.type.struct_def, body,
+                      nameprefix + field.name + "_");
+      } else {
+        *body += "  builder.write" + GenWriteMethod(field.value.type) + "(";
+        if (field.value.type.base_type == BASE_TYPE_BOOL) { *body += "+"; }
+        *body += nameprefix + field.name + ");\n";
+      }
+    }
+  }
+
+  void GenerateRootAccessor(StructDef &struct_def, std::string *code_ptr,
+                 std::string &code, std::string &object_name, bool size_prefixed) {
+    if (!struct_def.fixed) {
+      GenDocComment(code_ptr,
+                    GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") +
+                        GenTypeAnnotation(kParam, object_name + "=", "obj") +
+                        GenTypeAnnotation(kReturns, object_name, "", false));
+      std::string sizePrefixed("SizePrefixed");
+      if (lang_.language == IDLOptions::kTs) {
+        code += "static get" + (size_prefixed ? sizePrefixed : "") + "Root" + Verbose(struct_def, "As");
+        code += "(bb:flatbuffers.ByteBuffer, obj?:" + object_name +
+                "):" + object_name + " {\n";
+      } else {
+        code += object_name + ".get" + (size_prefixed ? sizePrefixed : "") + "Root" + Verbose(struct_def, "As");
+        code += " = function(bb, obj) {\n";
+      }
+      code += "  return (obj || new " + object_name;
+      code += ").__init(bb.readInt32(bb.position()) + bb.position(), bb);\n";
+      code += "};\n\n";
+    }
+  }
+
+  void GenerateFinisher(StructDef &struct_def, std::string *code_ptr,
+                 std::string &code, std::string &object_name, bool size_prefixed) {
+    if (parser_.root_struct_def_ == &struct_def) {
+      std::string sizePrefixed("SizePrefixed");
+      GenDocComment(
+          code_ptr,
+          GenTypeAnnotation(kParam, "flatbuffers.Builder", "builder") +
+              GenTypeAnnotation(kParam, "flatbuffers.Offset", "offset",
+                                false));
+
+      if (lang_.language == IDLOptions::kTs) {
+        code += "static finish" + (size_prefixed ? sizePrefixed : "") + Verbose(struct_def) + "Buffer";
+        code +=
+            "(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {\n";
+      } else {
+        code += object_name + ".finish" + (size_prefixed ? sizePrefixed : "") + Verbose(struct_def) + "Buffer";
+        code += " = function(builder, offset) {\n";
+      }
+
+      code += "  builder.finish(offset";
+      if (!parser_.file_identifier_.empty()) {
+        code += ", '" + parser_.file_identifier_ + "'";
+      }
+      if (size_prefixed) {
+        if (parser_.file_identifier_.empty()) {
+          code += ", undefined";
+        }
+        code += ", true";
+      }
+      code += ");\n";
+      code += "};\n\n";
+    }
+  }
+
+  // Generate an accessor struct with constructor for a flatbuffers struct.
+  void GenStruct(const Parser &parser, StructDef &struct_def,
+                 std::string *code_ptr, std::string *exports_ptr,
+                 imported_fileset &imported_files) {
+    if (struct_def.generated) return;
+    std::string &code = *code_ptr;
+    std::string &exports = *exports_ptr;
+
+    std::string object_name;
+    std::string object_namespace = GetNameSpace(struct_def);
+
+    // Emit constructor
+    if (lang_.language == IDLOptions::kTs) {
+      object_name = struct_def.name;
+      GenDocComment(struct_def.doc_comment, code_ptr, "@constructor");
+      if (!object_namespace.empty()) {
+        code += "export namespace " + object_namespace + "{\n";
+      }
+      code += "export class " + struct_def.name;
+      code += " {\n";
+      if (lang_.language != IDLOptions::kTs) {
+        code += "  /**\n";
+        code += "   * " + GenTypeAnnotation(kType, "flatbuffers.ByteBuffer", "");
+        code += "   */\n";
+      }
+      code += "  bb: flatbuffers.ByteBuffer|null = null;\n";
+      code += "\n";
+      if (lang_.language != IDLOptions::kTs) {
+        code += "  /**\n";
+        code += "   * " + GenTypeAnnotation(kType, "number", "");
+        code += "   */\n";
+      }
+      code += "  bb_pos:number = 0;\n";
+    } else {
+      bool isStatement = struct_def.defined_namespace->components.empty();
+      object_name = WrapInNameSpace(struct_def);
+      GenDocComment(struct_def.doc_comment, code_ptr, "@constructor");
+      if (isStatement) {
+        if (parser_.opts.use_goog_js_export_format) {
+          exports += "goog.exportSymbol('" + struct_def.name + "', " +
+                     struct_def.name + ");\n";
+        } else if (parser_.opts.use_ES6_js_export_format) {
+          exports += "export {" + struct_def.name + "};\n";
+        } else {
+          exports +=
+              "this." + struct_def.name + " = " + struct_def.name + ";\n";
+        }
+        code += "function " + object_name;
+      } else {
+        code += object_name + " = function";
+      }
+      code += "() {\n";
+      code += "  /**\n";
+      code += "   * " + GenTypeAnnotation(kType, "flatbuffers.ByteBuffer", "");
+      code += "   */\n";
+      code += "  this.bb = null;\n";
+      code += "\n";
+      code += "  /**\n";
+      code += "   * " + GenTypeAnnotation(kType, "number", "");
+      code += "   */\n";
+      code += "  this.bb_pos = 0;\n";
+      code += isStatement ? "}\n\n" : "};\n\n";
+    }
+
+    // Generate the __init method that sets the field in a pre-existing
+    // accessor object. This is to allow object reuse.
+    code += "/**\n";
+    code += " * " + GenTypeAnnotation(kParam, "number", "i");
+    code += " * " + GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb");
+    code += " * " + GenTypeAnnotation(kReturns, object_name, "");
+    code += " */\n";
+
+    if (lang_.language == IDLOptions::kTs) {
+      code +=
+          "__init(i:number, bb:flatbuffers.ByteBuffer):" + object_name + " {\n";
+    } else {
+      code += object_name + ".prototype.__init = function(i, bb) {\n";
+    }
+
+    code += "  this.bb_pos = i;\n";
+    code += "  this.bb = bb;\n";
+    code += "  return this;\n";
+    code += "};\n\n";
+
+    // Generate special accessors for the table that when used as the root of a
+    // FlatBuffer
+    GenerateRootAccessor(struct_def, code_ptr, code, object_name, false);
+    GenerateRootAccessor(struct_def, code_ptr, code, object_name, true);
+
+    // Generate the identifier check method
+    if (!struct_def.fixed && parser_.root_struct_def_ == &struct_def &&
+        !parser_.file_identifier_.empty()) {
+      GenDocComment(
+          code_ptr,
+          GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") +
+              GenTypeAnnotation(kReturns, "boolean", "", false));
+      if (lang_.language == IDLOptions::kTs) {
+        code +=
+            "static bufferHasIdentifier(bb:flatbuffers.ByteBuffer):boolean "
+            "{\n";
+      } else {
+        code += object_name + ".bufferHasIdentifier = function(bb) {\n";
+      }
+
+      code += "  return bb.__has_identifier('" + parser_.file_identifier_;
+      code += "');\n};\n\n";
+    }
+
+    // Emit field accessors
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+      auto offset_prefix =
+          "  var offset = " + GenBBAccess() + ".__offset(this.bb_pos, " +
+          NumToString(field.value.offset) + ");\n  return offset ? ";
+
+      // Emit a scalar field
+      if (IsScalar(field.value.type.base_type) ||
+          field.value.type.base_type == BASE_TYPE_STRING) {
+        GenDocComment(
+            field.doc_comment, code_ptr,
+            std::string(field.value.type.base_type == BASE_TYPE_STRING
+                            ? GenTypeAnnotation(kParam, "flatbuffers.Encoding=",
+                                                "optionalEncoding")
+                            : "") +
+                GenTypeAnnotation(kReturns,
+                                  GenTypeName(field.value.type, false, true),
+                                  "", false));
+        if (lang_.language == IDLOptions::kTs) {
+          std::string prefix = MakeCamel(field.name, false) + "(";
+          if (field.value.type.base_type == BASE_TYPE_STRING) {
+            code += prefix + "):string|null\n";
+            code += prefix + "optionalEncoding:flatbuffers.Encoding" +
+                    "):" + GenTypeName(field.value.type, false, true) + "\n";
+            code += prefix + "optionalEncoding?:any";
+          } else {
+            code += prefix;
+          }
+          if (field.value.type.enum_def) {
+            code +=
+                "):" +
+                GenPrefixedTypeName(GenTypeName(field.value.type, false, true),
+                                    field.value.type.enum_def->file) +
+                " {\n";
+
+            if (!parser_.opts.generate_all) {
+              imported_files.insert(field.value.type.enum_def->file);
+            }
+          } else {
+            code += "):" + GenTypeName(field.value.type, false, true) + " {\n";
+          }
+        } else {
+          code += object_name + ".prototype." + MakeCamel(field.name, false);
+          code += " = function(";
+          if (field.value.type.base_type == BASE_TYPE_STRING) {
+            code += "optionalEncoding";
+          }
+          code += ") {\n";
+        }
+
+        if (struct_def.fixed) {
+          code +=
+              "  return " +
+              GenGetter(field.value.type,
+                        "(this.bb_pos" + MaybeAdd(field.value.offset) + ")") +
+              ";\n";
+        } else {
+          std::string index = "this.bb_pos + offset";
+          if (field.value.type.base_type == BASE_TYPE_STRING) {
+            index += ", optionalEncoding";
+          }
+          code += offset_prefix +
+                  GenGetter(field.value.type, "(" + index + ")") + " : " +
+                  GenDefaultValue(field.value, GenBBAccess());
+          code += ";\n";
+        }
+      }
+
+      // Emit an object field
+      else {
+        switch (field.value.type.base_type) {
+          case BASE_TYPE_STRUCT: {
+            auto type = WrapInNameSpace(*field.value.type.struct_def);
+            GenDocComment(
+                field.doc_comment, code_ptr,
+                GenTypeAnnotation(kParam, type + "=", "obj") +
+                    GenTypeAnnotation(kReturns, type + "|null", "", false));
+            if (lang_.language == IDLOptions::kTs) {
+              type =
+                  GenPrefixedTypeName(type, field.value.type.struct_def->file);
+              code += MakeCamel(field.name, false);
+              code += "(obj?:" + type + "):" + type + "|null {\n";
+            } else {
+              code +=
+                  object_name + ".prototype." + MakeCamel(field.name, false);
+              code += " = function(obj) {\n";
+            }
+
+            if (struct_def.fixed) {
+              code += "  return (obj || new " + type;
+              code += ").__init(this.bb_pos";
+              code +=
+                  MaybeAdd(field.value.offset) + ", " + GenBBAccess() + ");\n";
+            } else {
+              code += offset_prefix + "(obj || new " + type + ").__init(";
+              code += field.value.type.struct_def->fixed
+                          ? "this.bb_pos + offset"
+                          : GenBBAccess() + ".__indirect(this.bb_pos + offset)";
+              code += ", " + GenBBAccess() + ") : null;\n";
+            }
+
+            if (lang_.language == IDLOptions::kTs && !parser_.opts.generate_all) {
+              imported_files.insert(field.value.type.struct_def->file);
+            }
+
+            break;
+          }
+
+          case BASE_TYPE_VECTOR: {
+            auto vectortype = field.value.type.VectorType();
+            auto vectortypename = GenTypeName(vectortype, false);
+            auto inline_size = InlineSize(vectortype);
+            auto index = GenBBAccess() +
+                         ".__vector(this.bb_pos + offset) + index" +
+                         MaybeScale(inline_size);
+            std::string args = GenTypeAnnotation(kParam, "number", "index");
+            std::string ret_type;
+            bool is_union = false;
+            switch (vectortype.base_type) {
+              case BASE_TYPE_STRUCT:
+                args += GenTypeAnnotation(kParam, vectortypename + "=", "obj");
+                ret_type = vectortypename;
+                break;
+              case BASE_TYPE_STRING:
+                args += GenTypeAnnotation(
+                    kParam, "flatbuffers.Encoding=", "optionalEncoding");
+                ret_type = vectortypename;
+                break;
+              case BASE_TYPE_UNION:
+                args += GenTypeAnnotation(kParam, "flatbuffers.Table=", "obj");
+                ret_type = "?flatbuffers.Table";
+                is_union = true;
+                break;
+              default: ret_type = vectortypename;
+            }
+            GenDocComment(
+                field.doc_comment, code_ptr,
+                args + GenTypeAnnotation(kReturns, ret_type, "", false));
+            if (lang_.language == IDLOptions::kTs) {
+              std::string prefix = MakeCamel(field.name, false);
+              if (is_union) { prefix += "<T extends flatbuffers.Table>"; }
+              prefix += "(index: number";
+              if (is_union) {
+                vectortypename = "T";
+                code += prefix + ", obj:T";
+              } else if (vectortype.base_type == BASE_TYPE_STRUCT) {
+                vectortypename = GenPrefixedTypeName(
+                    vectortypename, vectortype.struct_def->file);
+                code += prefix + ", obj?:" + vectortypename;
+
+                if (!parser_.opts.generate_all) {
+                  imported_files.insert(vectortype.struct_def->file);
+                }
+              } else if (vectortype.base_type == BASE_TYPE_STRING) {
+                code += prefix + "):string\n";
+                code += prefix + ",optionalEncoding:flatbuffers.Encoding" +
+                        "):" + vectortypename + "\n";
+                code += prefix + ",optionalEncoding?:any";
+              } else {
+                code += prefix;
+              }
+              code += "):" + vectortypename + "|null {\n";
+            } else {
+              code +=
+                  object_name + ".prototype." + MakeCamel(field.name, false);
+              code += " = function(index";
+              if (vectortype.base_type == BASE_TYPE_STRUCT || is_union) {
+                code += ", obj";
+              } else if (vectortype.base_type == BASE_TYPE_STRING) {
+                code += ", optionalEncoding";
+              }
+              code += ") {\n";
+            }
+
+            if (vectortype.base_type == BASE_TYPE_STRUCT) {
+              code += offset_prefix + "(obj || new " + vectortypename;
+              code += ").__init(";
+              code += vectortype.struct_def->fixed
+                          ? index
+                          : GenBBAccess() + ".__indirect(" + index + ")";
+              code += ", " + GenBBAccess() + ")";
+            } else {
+              if (is_union) {
+                index = "obj, " + index;
+              } else if (vectortype.base_type == BASE_TYPE_STRING) {
+                index += ", optionalEncoding";
+              }
+              code += offset_prefix + GenGetter(vectortype, "(" + index + ")");
+            }
+            code += " : ";
+            if (field.value.type.element == BASE_TYPE_BOOL) {
+              code += "false";
+            } else if (field.value.type.element == BASE_TYPE_LONG ||
+                       field.value.type.element == BASE_TYPE_ULONG) {
+              code += GenBBAccess() + ".createLong(0, 0)";
+            } else if (IsScalar(field.value.type.element)) {
+              if (field.value.type.enum_def) {
+                code += "/** " +
+                        GenTypeAnnotation(
+                            kType, WrapInNameSpace(*field.value.type.enum_def),
+                            "", false) +
+                        " */ (" + field.value.constant + ")";
+              } else {
+                code += "0";
+              }
+            } else {
+              code += "null";
+            }
+            code += ";\n";
+            break;
+          }
+
+          case BASE_TYPE_UNION:
+            GenDocComment(
+                field.doc_comment, code_ptr,
+                GenTypeAnnotation(kParam, "flatbuffers.Table", "obj") +
+                    GenTypeAnnotation(kReturns, "?flatbuffers.Table", "",
+                                      false));
+            if (lang_.language == IDLOptions::kTs) {
+              code += MakeCamel(field.name, false);
+              code += "<T extends flatbuffers.Table>(obj:T):T|null {\n";
+            } else {
+              code +=
+                  object_name + ".prototype." + MakeCamel(field.name, false);
+              code += " = function(obj) {\n";
+            }
+
+            code += offset_prefix +
+                    GenGetter(field.value.type, "(obj, this.bb_pos + offset)") +
+                    " : null;\n";
+            break;
+
+          default: FLATBUFFERS_ASSERT(0);
+        }
+      }
+      code += "};\n\n";
+
+      if (parser_.opts.use_goog_js_export_format) {
+        exports += "goog.exportProperty(" + object_name + ".prototype, '" +
+                   MakeCamel(field.name, false) + "', " + object_name +
+                   ".prototype." + MakeCamel(field.name, false) + ");\n";
+      }
+
+      // Adds the mutable scalar value to the output
+      if (IsScalar(field.value.type.base_type) && parser.opts.mutable_buffer) {
+        std::string annotations = GenTypeAnnotation(
+            kParam, GenTypeName(field.value.type, true), "value");
+        GenDocComment(
+            code_ptr,
+            annotations + GenTypeAnnotation(kReturns, "boolean", "", false));
+
+        if (lang_.language == IDLOptions::kTs) {
+          std::string type;
+          if (field.value.type.enum_def) {
+            type = GenPrefixedTypeName(GenTypeName(field.value.type, true),
+                                       field.value.type.enum_def->file);
+          } else {
+            type = GenTypeName(field.value.type, true);
+          }
+
+          code += "mutate_" + field.name + "(value:" + type + "):boolean {\n";
+        } else {
+          code += object_name + ".prototype.mutate_" + field.name +
+                  " = function(value) {\n";
+        }
+
+        code += "  var offset = " + GenBBAccess() + ".__offset(this.bb_pos, " +
+                NumToString(field.value.offset) + ");\n\n";
+        code += "  if (offset === 0) {\n";
+        code += "    return false;\n";
+        code += "  }\n\n";
+
+        // special case for bools, which are treated as uint8
+        code += "  " + GenBBAccess() + ".write" +
+                MakeCamel(GenType(field.value.type)) +
+                "(this.bb_pos + offset, ";
+        if (field.value.type.base_type == BASE_TYPE_BOOL &&
+            lang_.language == IDLOptions::kTs) {
+          code += "+";
+        }
+
+        code += "value);\n";
+        code += "  return true;\n";
+        code += "};\n\n";
+
+        if (parser_.opts.use_goog_js_export_format) {
+          exports += "goog.exportProperty(" + object_name +
+                     ".prototype, 'mutate_" + field.name + "', " + object_name +
+                     ".prototype.mutate_" + field.name + ");\n";
+        }
+      }
+
+      // Emit vector helpers
+      if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+        // Emit a length helper
+        GenDocComment(code_ptr,
+                      GenTypeAnnotation(kReturns, "number", "", false));
+        if (lang_.language == IDLOptions::kTs) {
+          code += MakeCamel(field.name, false);
+          code += "Length():number {\n" + offset_prefix;
+        } else {
+          code += object_name + ".prototype." + MakeCamel(field.name, false);
+          code += "Length = function() {\n" + offset_prefix;
+        }
+
+        code +=
+            GenBBAccess() + ".__vector_len(this.bb_pos + offset) : 0;\n};\n\n";
+
+        if (parser_.opts.use_goog_js_export_format) {
+          exports += "goog.exportProperty(" + object_name + ".prototype, '" +
+                     MakeCamel(field.name, false) + "Length', " + object_name +
+                     ".prototype." + MakeCamel(field.name, false) +
+                     "Length);\n";
+        }
+
+        // For scalar types, emit a typed array helper
+        auto vectorType = field.value.type.VectorType();
+        if (IsScalar(vectorType.base_type) && !IsLong(vectorType.base_type)) {
+          GenDocComment(code_ptr, GenTypeAnnotation(
+                                      kReturns, GenType(vectorType) + "Array",
+                                      "", false));
+
+          if (lang_.language == IDLOptions::kTs) {
+            code += MakeCamel(field.name, false);
+            code += "Array():" + GenType(vectorType) + "Array|null {\n" +
+                    offset_prefix;
+          } else {
+            code += object_name + ".prototype." + MakeCamel(field.name, false);
+            code += "Array = function() {\n" + offset_prefix;
+          }
+
+          code += "new " + GenType(vectorType) + "Array(" + GenBBAccess() +
+                  ".bytes().buffer, " + GenBBAccess() +
+                  ".bytes().byteOffset + " + GenBBAccess() +
+                  ".__vector(this.bb_pos + offset), " + GenBBAccess() +
+                  ".__vector_len(this.bb_pos + offset)) : null;\n};\n\n";
+
+          if (parser_.opts.use_goog_js_export_format) {
+            exports += "goog.exportProperty(" + object_name + ".prototype, '" +
+                       MakeCamel(field.name, false) + "Array', " + object_name +
+                       ".prototype." + MakeCamel(field.name, false) +
+                       "Array);\n";
+          }
+        }
+      }
+    }
+
+    // Emit a factory constructor
+    if (struct_def.fixed) {
+      std::string annotations =
+          GenTypeAnnotation(kParam, "flatbuffers.Builder", "builder");
+      std::string arguments;
+      GenStructArgs(struct_def, &annotations, &arguments, "");
+      GenDocComment(code_ptr, annotations + GenTypeAnnotation(
+                                                kReturns, "flatbuffers.Offset",
+                                                "", false));
+
+      if (lang_.language == IDLOptions::kTs) {
+        code += "static create" + Verbose(struct_def) +
+                "(builder:flatbuffers.Builder";
+        code += arguments + "):flatbuffers.Offset {\n";
+      } else {
+        code += object_name + ".create" + Verbose(struct_def);
+        code += " = function(builder";
+        code += arguments + ") {\n";
+      }
+
+      GenStructBody(struct_def, &code, "");
+      code += "  return builder.offset();\n};\n\n";
+    } else {
+      // Generate a method to start building a new object
+      GenDocComment(code_ptr, GenTypeAnnotation(kParam, "flatbuffers.Builder",
+                                                "builder", false));
+
+      if (lang_.language == IDLOptions::kTs) {
+        code += "static start" + Verbose(struct_def) +
+                "(builder:flatbuffers.Builder) {\n";
+      } else {
+        code += object_name + ".start" + Verbose(struct_def);
+        code += " = function(builder) {\n";
+      }
+
+      code += "  builder.startObject(" +
+              NumToString(struct_def.fields.vec.size()) + ");\n";
+      code += "};\n\n";
+
+      // Generate a set of static methods that allow table construction
+      for (auto it = struct_def.fields.vec.begin();
+           it != struct_def.fields.vec.end(); ++it) {
+        auto &field = **it;
+        if (field.deprecated) continue;
+        const auto argname = GetArgName(field);
+
+        // Generate the field insertion method
+        GenDocComment(
+            code_ptr,
+            GenTypeAnnotation(kParam, "flatbuffers.Builder", "builder") +
+                GenTypeAnnotation(kParam, GenTypeName(field.value.type, true),
+                                  argname, false));
+
+        if (lang_.language == IDLOptions::kTs) {
+          code += "static add" + MakeCamel(field.name);
+          code += "(builder:flatbuffers.Builder, " + argname + ":" +
+                  GetArgType(field) + ") {\n";
+        } else {
+          code += object_name + ".add" + MakeCamel(field.name);
+          code += " = function(builder, " + argname + ") {\n";
+        }
+
+        code += "  builder.addField" + GenWriteMethod(field.value.type) + "(";
+        code += NumToString(it - struct_def.fields.vec.begin()) + ", ";
+        if (field.value.type.base_type == BASE_TYPE_BOOL) { code += "+"; }
+        code += argname + ", ";
+        if (!IsScalar(field.value.type.base_type)) {
+          code += "0";
+        } else {
+          if (field.value.type.base_type == BASE_TYPE_BOOL) { code += "+"; }
+          code += GenDefaultValue(field.value, "builder");
+        }
+        code += ");\n};\n\n";
+
+        if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+          auto vector_type = field.value.type.VectorType();
+          auto alignment = InlineAlignment(vector_type);
+          auto elem_size = InlineSize(vector_type);
+
+          // Generate a method to create a vector from a JavaScript array
+          if (!IsStruct(vector_type)) {
+            GenDocComment(
+                code_ptr,
+                GenTypeAnnotation(kParam, "flatbuffers.Builder", "builder") +
+                    GenTypeAnnotation(
+                        kParam,
+                        "Array.<" + GenTypeName(vector_type, true) + ">",
+                        "data") +
+                    GenTypeAnnotation(kReturns, "flatbuffers.Offset", "",
+                                      false));
+
+            if (lang_.language == IDLOptions::kTs) {
+              code += "static create" + MakeCamel(field.name);
+              std::string type = GenTypeName(vector_type, true) + "[]";
+              if (type == "number[]") { type += " | Uint8Array"; }
+              code += "Vector(builder:flatbuffers.Builder, data:" + type +
+                      "):flatbuffers.Offset {\n";
+            } else {
+              code += object_name + ".create" + MakeCamel(field.name);
+              code += "Vector = function(builder, data) {\n";
+            }
+
+            code += "  builder.startVector(" + NumToString(elem_size);
+            code += ", data.length, " + NumToString(alignment) + ");\n";
+            code += "  for (var i = data.length - 1; i >= 0; i--) {\n";
+            code += "    builder.add" + GenWriteMethod(vector_type) + "(";
+            if (vector_type.base_type == BASE_TYPE_BOOL) { code += "+"; }
+            code += "data[i]);\n";
+            code += "  }\n";
+            code += "  return builder.endVector();\n";
+            code += "};\n\n";
+          }
+
+          // Generate a method to start a vector, data to be added manually
+          // after
+          GenDocComment(
+              code_ptr,
+              GenTypeAnnotation(kParam, "flatbuffers.Builder", "builder") +
+                  GenTypeAnnotation(kParam, "number", "numElems", false));
+
+          if (lang_.language == IDLOptions::kTs) {
+            code += "static start" + MakeCamel(field.name);
+            code += "Vector(builder:flatbuffers.Builder, numElems:number) {\n";
+          } else {
+            code += object_name + ".start" + MakeCamel(field.name);
+            code += "Vector = function(builder, numElems) {\n";
+          }
+
+          code += "  builder.startVector(" + NumToString(elem_size);
+          code += ", numElems, " + NumToString(alignment) + ");\n";
+          code += "};\n\n";
+        }
+      }
+
+      // Generate a method to stop building a new object
+      GenDocComment(
+          code_ptr,
+          GenTypeAnnotation(kParam, "flatbuffers.Builder", "builder") +
+              GenTypeAnnotation(kReturns, "flatbuffers.Offset", "", false));
+
+      if (lang_.language == IDLOptions::kTs) {
+        code += "static end" + Verbose(struct_def);
+        code += "(builder:flatbuffers.Builder):flatbuffers.Offset {\n";
+      } else {
+        code += object_name + ".end" + Verbose(struct_def);
+        code += " = function(builder) {\n";
+      }
+
+      code += "  var offset = builder.endObject();\n";
+      for (auto it = struct_def.fields.vec.begin();
+           it != struct_def.fields.vec.end(); ++it) {
+        auto &field = **it;
+        if (!field.deprecated && field.required) {
+          code += "  builder.requiredField(offset, ";
+          code += NumToString(field.value.offset);
+          code += "); // " + field.name + "\n";
+        }
+      }
+      code += "  return offset;\n";
+      code += "};\n\n";
+
+      // Generate the methods to complete buffer construction
+      GenerateFinisher(struct_def, code_ptr, code, object_name, false);
+      GenerateFinisher(struct_def, code_ptr, code, object_name, true);
+
+      // Generate a convenient CreateX function
+      if (lang_.language == IDLOptions::kJs) {
+        std::string paramDoc =
+            GenTypeAnnotation(kParam, "flatbuffers.Builder", "builder");
+        for (auto it = struct_def.fields.vec.begin();
+             it != struct_def.fields.vec.end(); ++it) {
+          const auto &field = **it;
+          if (field.deprecated)
+            continue;
+          paramDoc +=
+              GenTypeAnnotation(kParam, GetArgType(field), GetArgName(field));
+        }
+        paramDoc +=
+            GenTypeAnnotation(kReturns, "flatbuffers.Offset", "", false);
+
+        GenDocComment(code_ptr, paramDoc);
+      }
+
+      if (lang_.language == IDLOptions::kTs) {
+        code += "static create" + Verbose(struct_def);
+        code += "(builder:flatbuffers.Builder";
+      } else {
+        code += object_name + ".create" + Verbose(struct_def);
+        code += " = function(builder";
+      }
+      for (auto it = struct_def.fields.vec.begin();
+           it != struct_def.fields.vec.end(); ++it) {
+        const auto &field = **it;
+        if (field.deprecated)
+          continue;
+
+        if (lang_.language == IDLOptions::kTs) {
+          code += ", " + GetArgName(field) + ":" + GetArgType(field);
+        } else {
+          code += ", " + GetArgName(field);
+        }
+      }
+
+      if (lang_.language == IDLOptions::kTs) {
+        code += "):flatbuffers.Offset {\n";
+        code += "  " + struct_def.name + ".start" + Verbose(struct_def) +
+                "(builder);\n";
+      } else {
+        code += ") {\n";
+        code += "  " + object_name + ".start" + Verbose(struct_def) +
+                "(builder);\n";
+      }
+
+      std::string methodPrefix =
+          lang_.language == IDLOptions::kTs ? struct_def.name : object_name;
+      for (auto it = struct_def.fields.vec.begin();
+           it != struct_def.fields.vec.end(); ++it) {
+        const auto &field = **it;
+        if (field.deprecated)
+          continue;
+
+        code += "  " + methodPrefix + ".add" + MakeCamel(field.name) + "(";
+        code += "builder, " + GetArgName(field) + ");\n";
+      }
+
+      code += "  return " + methodPrefix + ".end" + Verbose(struct_def) +
+              "(builder);\n";
+      code += "}\n";
+      if (lang_.language == IDLOptions::kJs)
+        code += "\n";
+    }
+
+    if (lang_.language == IDLOptions::kTs) {
+      if (!object_namespace.empty()) {
+        code += "}\n";
+      }
+      code += "}\n";
+    }
+  }
+
+  std::string GetArgType(const FieldDef &field) {
+    if (field.value.type.enum_def)
+      return GenPrefixedTypeName(GenTypeName(field.value.type, true),
+                                 field.value.type.enum_def->file);
+    return GenTypeName(field.value.type, true);
+  }
+
+  static std::string GetArgName(const FieldDef &field) {
+    auto argname = MakeCamel(field.name, false);
+    if (!IsScalar(field.value.type.base_type)) { argname += "Offset"; }
+
+    return argname;
+  }
+
+  std::string Verbose(const StructDef &struct_def,
+                      const char* prefix = "")
+  {
+    return parser_.opts.js_ts_short_names ? "" : prefix + struct_def.name;
+  }
+};
+}  // namespace jsts
+
+bool GenerateJSTS(const Parser &parser, const std::string &path,
+                  const std::string &file_name) {
+  jsts::JsTsGenerator generator(parser, path, file_name);
+  return generator.generate();
+}
+
+std::string JSTSMakeRule(const Parser &parser, const std::string &path,
+                         const std::string &file_name) {
+  FLATBUFFERS_ASSERT(parser.opts.lang <= IDLOptions::kMAX);
+  const auto &lang = GetJsLangParams(parser.opts.lang);
+
+  std::string filebase =
+      flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
+  std::string make_rule = GeneratedFileName(path, filebase, lang) + ": ";
+
+  auto included_files = parser.GetIncludedFilesRecursive(file_name);
+  for (auto it = included_files.begin(); it != included_files.end(); ++it) {
+    make_rule += " " + *it;
+  }
+  return make_rule;
+}
+
+}  // namespace flatbuffers
diff --git a/src/idl_gen_json_schema.cpp b/src/idl_gen_json_schema.cpp
new file mode 100644
index 0000000..27e2cd4
--- /dev/null
+++ b/src/idl_gen_json_schema.cpp
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <iostream>
+#include "flatbuffers/code_generators.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+namespace flatbuffers {
+
+static std::string GeneratedFileName(const std::string &path,
+                                     const std::string &file_name) {
+  return path + file_name + ".schema.json";
+}
+
+namespace jsons {
+
+std::string GenNativeType(BaseType type) {
+  switch (type) {
+    case BASE_TYPE_BOOL: return "boolean";
+    case BASE_TYPE_CHAR:
+    case BASE_TYPE_UCHAR:
+    case BASE_TYPE_SHORT:
+    case BASE_TYPE_USHORT:
+    case BASE_TYPE_INT:
+    case BASE_TYPE_UINT:
+    case BASE_TYPE_LONG:
+    case BASE_TYPE_ULONG:
+    case BASE_TYPE_FLOAT:
+    case BASE_TYPE_DOUBLE: return "number";
+    case BASE_TYPE_STRING: return "string";
+    case BASE_TYPE_ARRAY: return "array";
+    default: return "";
+  }
+}
+
+template<class T> std::string GenFullName(const T *enum_def) {
+  std::string full_name;
+  const auto &name_spaces = enum_def->defined_namespace->components;
+  for (auto ns = name_spaces.cbegin(); ns != name_spaces.cend(); ++ns) {
+    full_name.append(*ns + "_");
+  }
+  full_name.append(enum_def->name);
+  return full_name;
+}
+
+template<class T> std::string GenTypeRef(const T *enum_def) {
+  return "\"$ref\" : \"#/definitions/" + GenFullName(enum_def) + "\"";
+}
+
+std::string GenType(const std::string &name) {
+  return "\"type\" : \"" + name + "\"";
+}
+
+std::string GenType(const Type &type) {
+  if (type.enum_def != nullptr && !type.enum_def->is_union) {
+    // it is a reference to an enum type
+    return GenTypeRef(type.enum_def);
+  }
+  switch (type.base_type) {
+    case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH();  // fall thru
+    case BASE_TYPE_VECTOR: {
+      std::string typeline;
+      typeline.append("\"type\" : \"array\", \"items\" : { ");
+      if (type.element == BASE_TYPE_STRUCT) {
+        typeline.append(GenTypeRef(type.struct_def));
+      } else {
+        typeline.append(GenType(GenNativeType(type.element)));
+      }
+      typeline.append(" }");
+      return typeline;
+    }
+    case BASE_TYPE_STRUCT: {
+      return GenTypeRef(type.struct_def);
+    }
+    case BASE_TYPE_UNION: {
+      std::string union_type_string("\"anyOf\": [");
+      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; }
+        if (union_type->union_type.base_type == BASE_TYPE_STRUCT) {
+          union_type_string.append(
+              "{ " + GenTypeRef(union_type->union_type.struct_def) + " }");
+        }
+        if (union_type != *type.enum_def->Vals().rbegin()) {
+          union_type_string.append(",");
+        }
+      }
+      union_type_string.append("]");
+      return union_type_string;
+    }
+    case BASE_TYPE_UTYPE: return GenTypeRef(type.enum_def);
+    default: return GenType(GenNativeType(type.base_type));
+  }
+}
+
+class JsonSchemaGenerator : public BaseGenerator {
+ private:
+  CodeWriter code_;
+
+ public:
+  JsonSchemaGenerator(const Parser &parser, const std::string &path,
+                      const std::string &file_name)
+      : BaseGenerator(parser, path, file_name, "", "") {}
+
+  explicit JsonSchemaGenerator(const BaseGenerator &base_generator)
+      : BaseGenerator(base_generator) {}
+
+  bool generate() {
+    code_.Clear();
+    code_ += "{";
+    code_ += "  \"$schema\": \"http://json-schema.org/draft-04/schema#\",";
+    code_ += "  \"definitions\": {";
+    for (auto e = parser_.enums_.vec.cbegin(); e != parser_.enums_.vec.cend();
+         ++e) {
+      code_ += "    \"" + GenFullName(*e) + "\" : {";
+      code_ += "      " + GenType("string") + ",";
+      std::string enumdef("      \"enum\": [");
+      for (auto enum_value = (*e)->Vals().begin();
+           enum_value != (*e)->Vals().end(); ++enum_value) {
+        enumdef.append("\"" + (*enum_value)->name + "\"");
+        if (*enum_value != (*e)->Vals().back()) { enumdef.append(", "); }
+      }
+      enumdef.append("]");
+      code_ += enumdef;
+      code_ += "    },";  // close type
+    }
+    for (auto s = parser_.structs_.vec.cbegin();
+         s != parser_.structs_.vec.cend(); ++s) {
+      const auto &structure = *s;
+      code_ += "    \"" + GenFullName(structure) + "\" : {";
+      code_ += "      " + GenType("object") + ",";
+      std::string comment;
+      const auto &comment_lines = structure->doc_comment;
+      for (auto comment_line = comment_lines.cbegin();
+           comment_line != comment_lines.cend(); ++comment_line) {
+        comment.append(*comment_line);
+      }
+      if (comment.size() > 0) {
+        code_ += "      \"description\" : \"" + comment + "\",";
+      }
+      code_ += "      \"properties\" : {";
+
+      const auto &properties = structure->fields.vec;
+      for (auto prop = properties.cbegin(); prop != properties.cend(); ++prop) {
+        const auto &property = *prop;
+        std::string arrayInfo = "";
+        if (IsArray(property->value.type)) {
+          arrayInfo = ",\n                \"minItems\": " +
+                      NumToString(property->value.type.fixed_length) +
+                      ",\n                \"maxItems\": " +
+                      NumToString(property->value.type.fixed_length);
+        }
+        std::string typeLine =
+            "        \"" + property->name + "\" : {\n" + "                " +
+            GenType(property->value.type) + arrayInfo + "\n              }";
+        if (property != properties.back()) { typeLine.append(","); }
+        code_ += typeLine;
+      }
+      code_ += "      },";  // close properties
+
+      std::vector<FieldDef *> requiredProperties;
+      std::copy_if(properties.begin(), properties.end(),
+                   back_inserter(requiredProperties),
+                   [](FieldDef const *prop) { return prop->required; });
+      if (requiredProperties.size() > 0) {
+        std::string required_string("      \"required\" : [");
+        for (auto req_prop = requiredProperties.cbegin();
+             req_prop != requiredProperties.cend(); ++req_prop) {
+          required_string.append("\"" + (*req_prop)->name + "\"");
+          if (*req_prop != requiredProperties.back()) {
+            required_string.append(", ");
+          }
+        }
+        required_string.append("],");
+        code_ += required_string;
+      }
+      code_ += "      \"additionalProperties\" : false";
+      std::string closeType("    }");
+      if (*s != parser_.structs_.vec.back()) { closeType.append(","); }
+      code_ += closeType;  // close type
+    }
+    code_ += "  },";  // close definitions
+
+    // mark root type
+    code_ += "  \"$ref\" : \"#/definitions/" +
+             GenFullName(parser_.root_struct_def_) + "\"";
+
+    code_ += "}";  // close schema root
+    const std::string file_path = GeneratedFileName(path_, file_name_);
+    const std::string final_code = code_.ToString();
+    return SaveFile(file_path.c_str(), final_code, false);
+  }
+};
+}  // namespace jsons
+
+bool GenerateJsonSchema(const Parser &parser, const std::string &path,
+                        const std::string &file_name) {
+  jsons::JsonSchemaGenerator generator(parser, path, file_name);
+  return generator.generate();
+}
+}  // namespace flatbuffers
diff --git a/src/idl_gen_kotlin.cpp b/src/idl_gen_kotlin.cpp
new file mode 100644
index 0000000..3ced7b3
--- /dev/null
+++ b/src/idl_gen_kotlin.cpp
@@ -0,0 +1,1527 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// independent from idl_parser, since this code is not needed for most clients
+
+#include <functional>
+#include <unordered_set>
+#include "flatbuffers/code_generators.h"
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+#if defined(FLATBUFFERS_CPP98_STL)
+#include <cctype>
+#endif  // defined(FLATBUFFERS_CPP98_STL)
+
+namespace flatbuffers {
+
+namespace kotlin {
+
+typedef std::map<std::string, std::pair<std::string, std::string> > FbbParamMap;
+static TypedFloatConstantGenerator KotlinFloatGen("Double.", "Float.", "NaN",
+                                                  "POSITIVE_INFINITY",
+                                                  "NEGATIVE_INFINITY");
+
+static const CommentConfig comment_config = {"/**", " *", " */"};
+static const std::string ident_pad = "    ";
+static const char *keywords[] = {
+    "package",  "as",     "typealias", "class",  "this",   "super",
+    "val",      "var",    "fun",       "for",    "null",   "true",
+    "false",    "is",     "in",        "throw",  "return", "break",
+    "continue", "object", "if",        "try",    "else",   "while",
+    "do",       "when",   "interface", "typeof", "Any",    "Character"};
+
+// Escape Keywords
+static std::string Esc(const std::string &name) {
+  for (size_t i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) {
+    if (name == keywords[i]) {
+      return MakeCamel(name + "_", false);
+    }
+  }
+
+  return MakeCamel(name, false);
+}
+
+class KotlinGenerator : public BaseGenerator {
+ public:
+  KotlinGenerator(const Parser &parser, const std::string &path,
+                  const std::string &file_name)
+      : BaseGenerator(parser, path, file_name, "", "."),
+        cur_name_space_(nullptr) {}
+
+  KotlinGenerator &operator=(const KotlinGenerator &);
+  bool generate() FLATBUFFERS_OVERRIDE {
+    std::string one_file_code;
+
+    cur_name_space_ = parser_.current_namespace_;
+    for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
+         ++it) {
+      CodeWriter enumWriter(ident_pad);
+      auto &enum_def = **it;
+      if (!parser_.opts.one_file) cur_name_space_ = enum_def.defined_namespace;
+      GenEnum(enum_def, enumWriter);
+      if (parser_.opts.one_file) {
+        one_file_code += enumWriter.ToString();
+      } else {
+        if (!SaveType(enum_def.name, *enum_def.defined_namespace,
+                      enumWriter.ToString(), false))
+          return false;
+      }
+    }
+
+    for (auto it = parser_.structs_.vec.begin();
+         it != parser_.structs_.vec.end(); ++it) {
+      CodeWriter structWriter(ident_pad);
+      auto &struct_def = **it;
+      if (!parser_.opts.one_file)
+        cur_name_space_ = struct_def.defined_namespace;
+      GenStruct(struct_def, structWriter);
+      if (parser_.opts.one_file) {
+        one_file_code += structWriter.ToString();
+      } else {
+        if (!SaveType(struct_def.name, *struct_def.defined_namespace,
+                      structWriter.ToString(), true))
+          return false;
+      }
+    }
+
+    if (parser_.opts.one_file) {
+      return SaveType(file_name_, *parser_.current_namespace_, one_file_code,
+                      true);
+    }
+    return true;
+  }
+
+  // Save out the generated code for a single class while adding
+  // declaration boilerplate.
+  bool SaveType(const std::string &defname, const Namespace &ns,
+                const std::string &classcode, bool needs_includes) const {
+    if (!classcode.length()) return true;
+
+    std::string code =
+        "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n";
+
+    std::string namespace_name = FullNamespace(".", ns);
+    if (!namespace_name.empty()) {
+      code += "package " + namespace_name;
+      code += "\n\n";
+    }
+    if (needs_includes) {
+      code += "import java.nio.*\n";
+      code += "import kotlin.math.sign\n";
+      code += "import com.google.flatbuffers.*\n\n";
+    }
+    code += classcode;
+    auto filename = NamespaceDir(ns) + defname + ".kt";
+    return SaveFile(filename.c_str(), code, false);
+  }
+
+  const Namespace *CurrentNameSpace() const FLATBUFFERS_OVERRIDE {
+    return cur_name_space_;
+  }
+
+  static bool IsEnum(const Type &type) {
+    return type.enum_def != nullptr && IsInteger(type.base_type);
+  }
+
+  static std::string GenTypeBasic(const BaseType &type) {
+    // clang-format off
+        static const char * const kotlin_typename[] = {
+    #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+        CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
+    #KTYPE,
+        FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+    #undef FLATBUFFERS_TD
+        };
+        return kotlin_typename[type];
+
+    }
+
+    std::string GenTypePointer(const Type &type) const {
+        switch (type.base_type) {
+        case BASE_TYPE_STRING:
+            return "String";
+        case BASE_TYPE_VECTOR:
+            return GenTypeGet(type.VectorType());
+        case BASE_TYPE_STRUCT:
+            return WrapInNameSpace(*type.struct_def);
+        default:
+            return "Table";
+        }
+    }
+
+    std::string GenTypeGet(const Type &type) const {
+        return IsScalar(type.base_type) ? GenTypeBasic(type.base_type)
+                                        : GenTypePointer(type);
+    }
+
+    std::string GenEnumDefaultValue(const FieldDef &field) const {
+        auto &value = field.value;
+        FLATBUFFERS_ASSERT(value.type.enum_def);
+        auto &enum_def = *value.type.enum_def;
+        auto enum_val = enum_def.FindByValue(value.constant);
+        return enum_val ? (WrapInNameSpace(enum_def) + "." + enum_val->name)
+                        : value.constant;
+    }
+
+
+     // Generate default values to compare against a default value when
+     // `force_defaults` is `false`.
+     // Main differences are:
+     // - Floats are upcasted to doubles
+     // - Unsigned are casted to signed
+    std::string GenFBBDefaultValue(const FieldDef &field) const {
+        auto out = GenDefaultValue(field, true);
+        // All FlatBufferBuilder default floating point values are doubles
+        if (field.value.type.base_type == BASE_TYPE_FLOAT) {
+            if (out.find("Float") != std::string::npos) {
+                out.replace(0, 5, "Double");
+            }
+        }
+        //Guarantee all values are doubles
+        if (out.back() == 'f')
+            out.pop_back();
+        return out;
+    }
+
+
+    // FlatBufferBuilder only store signed types, so this function
+    // returns a cast for unsigned values
+    std::string GenFBBValueCast(const FieldDef &field) const {
+        if (IsUnsigned(field.value.type.base_type)) {
+            return CastToSigned(field.value.type);
+        }
+        return "";
+    }
+
+    std::string GenDefaultValue(const FieldDef &field,
+                                bool force_signed = false) const {
+        auto &value = field.value;
+        auto base_type = field.value.type.base_type;
+        if (IsFloat(base_type)) {
+            auto val = KotlinFloatGen.GenFloatConstant(field);
+            if (base_type == BASE_TYPE_DOUBLE &&
+                    val.back() == 'f') {
+                val.pop_back();
+            }
+            return val;
+        }
+
+        if (base_type  == BASE_TYPE_BOOL) {
+            return value.constant == "0" ? "false" : "true";
+        }
+
+        std::string suffix = "";
+
+        if (base_type == BASE_TYPE_LONG || !force_signed) {
+            suffix = LiteralSuffix(base_type);
+        }
+        return value.constant + suffix;
+    }
+
+    void GenEnum(EnumDef &enum_def, CodeWriter &writer) const {
+        if (enum_def.generated) return;
+
+        GenerateComment(enum_def.doc_comment, writer, &comment_config);
+
+        writer += "@Suppress(\"unused\")";
+        writer += "@ExperimentalUnsignedTypes";
+        writer += "class " + Esc(enum_def.name) + " private constructor() {";
+        writer.IncrementIdentLevel();
+
+        GenerateCompanionObject(writer, [&](){
+            // Write all properties
+            auto vals = enum_def.Vals();
+            for (auto it = vals.begin(); it != vals.end(); ++it) {
+                auto &ev = **it;
+                auto field_type = GenTypeBasic(enum_def.underlying_type.base_type);
+                auto val = enum_def.ToString(ev);
+                auto suffix = LiteralSuffix(enum_def.underlying_type.base_type);
+                writer.SetValue("name", Esc(ev.name));
+                writer.SetValue("type", field_type);
+                writer.SetValue("val", val + suffix);
+                GenerateComment(ev.doc_comment, writer, &comment_config);
+                writer += "const val {{name}}: {{type}} = {{val}}";
+            }
+
+            // Generate a generate string table for enum values.
+            // Problem is, if values are very sparse that could generate really
+            // big tables. Ideally in that case we generate a map lookup
+            // instead, but for the moment we simply don't output a table at all.
+            auto range = enum_def.Distance();
+            // Average distance between values above which we consider a table
+            // "too sparse". Change at will.
+            static const uint64_t kMaxSparseness = 5;
+            if (range / static_cast<uint64_t>(enum_def.size()) < kMaxSparseness) {
+                GeneratePropertyOneLine(writer, "names", "Array<String>",
+                               [&](){
+                    writer += "arrayOf(\\";
+                    auto val = enum_def.Vals().front();
+                    for (auto it = vals.begin(); it != vals.end(); ++it) {
+                        auto ev = *it;
+                        for (auto k = enum_def.Distance(val, ev); k > 1; --k)
+                            writer += "\"\", \\";
+                        val = ev;
+                        writer += "\"" + (*it)->name + "\"\\";
+                        if (it+1 != vals.end()) {
+                            writer += ", \\";
+                        }
+                    }
+                    writer += ")";
+                });
+                GenerateFunOneLine(writer, "name", "e: Int", "String", [&](){
+                    writer += "names[e\\";
+                    if (enum_def.MinValue()->IsNonZero())
+                        writer += " - " + enum_def.MinValue()->name + ".toInt()\\";
+                    writer += "]";
+                });
+            }
+        });
+        writer.DecrementIdentLevel();
+        writer += "}";
+    }
+
+    // Returns the function name that is able to read a value of the given type.
+    std::string ByteBufferGetter(const Type &type, std::string bb_var_name) const {
+        switch (type.base_type) {
+        case BASE_TYPE_STRING:
+            return "__string";
+        case BASE_TYPE_STRUCT:
+            return "__struct";
+        case BASE_TYPE_UNION:
+            return "__union";
+        case BASE_TYPE_VECTOR:
+            return ByteBufferGetter(type.VectorType(), bb_var_name);
+        case BASE_TYPE_INT:
+        case BASE_TYPE_UINT:
+            return bb_var_name + ".getInt";
+        case BASE_TYPE_SHORT:
+        case BASE_TYPE_USHORT:
+            return bb_var_name + ".getShort";
+        case BASE_TYPE_ULONG:
+        case BASE_TYPE_LONG:
+            return bb_var_name + ".getLong";
+        case BASE_TYPE_FLOAT:
+            return bb_var_name + ".getFloat";
+        case BASE_TYPE_DOUBLE:
+            return bb_var_name + ".getDouble";
+        case BASE_TYPE_CHAR:
+        case BASE_TYPE_UCHAR:
+        case BASE_TYPE_NONE:
+        case BASE_TYPE_UTYPE:
+            return bb_var_name + ".get";
+        case BASE_TYPE_BOOL:
+            return "0.toByte() != " + bb_var_name + ".get";
+        default:
+            return bb_var_name + ".get" + MakeCamel(GenTypeBasic(type.base_type));
+        }
+    }
+
+    std::string ByteBufferSetter(const Type &type) const {
+        if (IsScalar(type.base_type)) {
+            switch (type.base_type) {
+            case BASE_TYPE_INT:
+            case BASE_TYPE_UINT:
+                return "bb.putInt";
+            case BASE_TYPE_SHORT:
+            case BASE_TYPE_USHORT:
+                return "bb.putShort";
+            case BASE_TYPE_ULONG:
+            case BASE_TYPE_LONG:
+                return "bb.putLong";
+            case BASE_TYPE_FLOAT:
+                return "bb.putFloat";
+            case BASE_TYPE_DOUBLE:
+                return "bb.putDouble";
+            case BASE_TYPE_CHAR:
+            case BASE_TYPE_UCHAR:
+            case BASE_TYPE_BOOL:
+            case BASE_TYPE_NONE:
+            case BASE_TYPE_UTYPE:
+                return "bb.put";
+            default:
+                return "bb.put" + MakeCamel(GenTypeBasic(type.base_type));
+            }
+        }
+        return "";
+    }
+
+    // Returns the function name that is able to read a value of the given type.
+    std::string GenLookupByKey(flatbuffers::FieldDef *key_field,
+                               const std::string &bb_var_name,
+                               const char *num = nullptr) const {
+        auto type = key_field->value.type;
+        return ByteBufferGetter(type, bb_var_name) + "(" + GenOffsetGetter(key_field, num) + ")";
+
+    }
+
+    // Returns the method name for use with add/put calls.
+    static std::string GenMethod(const Type &type) {
+        return IsScalar(type.base_type) ? ToSignedType(type)
+                                        : (IsStruct(type) ? "Struct" : "Offset");
+    }
+
+    // Recursively generate arguments for a constructor, to deal with nested
+    // structs.
+    static void GenStructArgs(const StructDef &struct_def, CodeWriter &writer,
+                              const char *nameprefix) {
+        for (auto it = struct_def.fields.vec.begin();
+             it != struct_def.fields.vec.end(); ++it) {
+            auto &field = **it;
+            if (IsStruct(field.value.type)) {
+                // Generate arguments for a struct inside a struct. To ensure
+                // names don't clash, and to make it obvious these arguments are
+                // constructing a nested struct, prefix the name with the field
+                // name.
+                GenStructArgs(*field.value.type.struct_def, writer,
+                              (nameprefix + (field.name + "_")).c_str());
+            } else {
+                writer += std::string(", ") + nameprefix + "\\";
+                writer += MakeCamel(field.name) + ": \\";
+                writer += GenTypeBasic(field.value.type.base_type) + "\\";
+            }
+        }
+    }
+
+    // Recusively generate struct construction statements of the form:
+    // builder.putType(name);
+    // and insert manual padding.
+    static void GenStructBody(const StructDef &struct_def, CodeWriter &writer,
+                              const char *nameprefix) {
+        writer.SetValue("align", NumToString(struct_def.minalign));
+        writer.SetValue("size", NumToString(struct_def.bytesize));
+        writer += "builder.prep({{align}}, {{size}})";
+        auto fields_vec = struct_def.fields.vec;
+        for (auto it = fields_vec.rbegin(); it != fields_vec.rend(); ++it) {
+            auto &field = **it;
+
+            if (field.padding) {
+                writer.SetValue("pad", NumToString(field.padding));
+                writer += "builder.pad({{pad}})";
+            }
+            if (IsStruct(field.value.type)) {
+                GenStructBody(*field.value.type.struct_def, writer,
+                              (nameprefix + (field.name + "_")).c_str());
+            } else {
+                writer.SetValue("type", GenMethod(field.value.type));
+                writer.SetValue("argname", nameprefix +
+                              MakeCamel(field.name, false));
+                writer.SetValue("cast", CastToSigned(field.value.type));
+                writer += "builder.put{{type}}({{argname}}{{cast}})";
+            }
+        }
+    }
+
+    std::string GenByteBufferLength(const char *bb_name) const {
+        std::string bb_len = bb_name;
+        bb_len += ".capacity()";
+        return bb_len;
+    }
+
+    std::string GenOffsetGetter(flatbuffers::FieldDef *key_field,
+                                const char *num = nullptr) const {
+        std::string key_offset = "__offset(" +
+                NumToString(key_field->value.offset) + ", ";
+        if (num) {
+            key_offset += num;
+            key_offset += ", _bb)";
+        } else {
+            key_offset += GenByteBufferLength("bb");
+            key_offset += " - tableOffset, bb)";
+        }
+        return key_offset;
+    }
+
+    void GenStruct(StructDef &struct_def, CodeWriter &writer) const {
+        if (struct_def.generated) return;
+
+        GenerateComment(struct_def.doc_comment, writer, &comment_config);
+        auto fixed = struct_def.fixed;
+
+        writer.SetValue("struct_name", Esc(struct_def.name));
+        writer.SetValue("superclass", fixed ? "Struct" : "Table");
+
+        writer += "@Suppress(\"unused\")";
+        writer += "@ExperimentalUnsignedTypes";
+        writer += "class {{struct_name}} : {{superclass}}() {\n";
+
+        writer.IncrementIdentLevel();
+
+        {
+            // Generate the __init() method that sets the field in a pre-existing
+            // accessor object. This is to allow object reuse.
+            GenerateFun(writer, "__init", "_i: Int, _bb: ByteBuffer", "", [&]() {
+                writer += "__reset(_i, _bb)";
+            });
+
+            // Generate assign method
+            GenerateFun(writer, "__assign", "_i: Int, _bb: ByteBuffer",
+                        Esc(struct_def.name), [&]() {
+                writer += "__init(_i, _bb)";
+                writer += "return this";
+            });
+
+            // Generate all getters
+            GenerateStructGetters(struct_def, writer);
+
+            // Generate Static Fields
+            GenerateCompanionObject(writer, [&](){
+
+                if (!struct_def.fixed) {
+                    FieldDef *key_field = nullptr;
+
+                    // Generate verson check method.
+                    // Force compile time error if not using the same version
+                    // runtime.
+                    GenerateFunOneLine(writer, "validateVersion", "", "", [&](){
+                        writer += "Constants.FLATBUFFERS_1_11_1()";
+                    });
+
+                    GenerateGetRootAsAccessors(Esc(struct_def.name), writer);
+                    GenerateBufferHasIdentifier(struct_def, writer);
+                    GenerateTableCreator(struct_def, writer);
+
+                    GenerateStartStructMethod(struct_def, writer);
+
+                    // Static Add for fields
+                    auto fields = struct_def.fields.vec;
+                    int field_pos = -1;
+                    for (auto it = fields.begin(); it != fields.end(); ++it) {
+                        auto &field = **it;
+                        field_pos++;
+                        if (field.deprecated) continue;
+                        if (field.key) key_field = &field;
+                        GenerateAddField(NumToString(field_pos), field, writer);
+
+                        if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+                            auto vector_type = field.value.type.VectorType();
+                            if (!IsStruct(vector_type)) {
+                                GenerateCreateVectorField(field, writer);
+                            }
+                            GenerateStartVectorField(field, writer);
+                        }
+                    }
+
+                    GenerateEndStructMethod(struct_def, writer);
+                    auto file_identifier = parser_.file_identifier_;
+                    if (parser_.root_struct_def_ == &struct_def) {
+                        GenerateFinishStructBuffer(struct_def,
+                                                   file_identifier,
+                                                   writer);
+                        GenerateFinishSizePrefixed(struct_def,
+                                                   file_identifier,
+                                                   writer);
+                    }
+
+                    if (struct_def.has_key) {
+                        GenerateLookupByKey(key_field, struct_def, writer);
+                    }
+                } else {
+                    GenerateStaticConstructor(struct_def, writer);
+                }
+            });
+        }
+
+        // class closing
+        writer.DecrementIdentLevel();
+        writer += "}";
+    }
+
+    // TODO: move key_field to reference instead of pointer
+    void GenerateLookupByKey(FieldDef *key_field, StructDef &struct_def,
+                             CodeWriter &writer) const {
+        std::stringstream params;
+        params << "obj: " << Esc(struct_def.name) << "?" << ", ";
+        params << "vectorLocation: Int, ";
+        params << "key: " <<  GenTypeGet(key_field->value.type) << ", ";
+        params << "bb: ByteBuffer";
+
+        auto statements = [&]() {
+            auto base_type = key_field->value.type.base_type;
+            writer.SetValue("struct_name", Esc(struct_def.name));
+            if (base_type == BASE_TYPE_STRING) {
+                writer += "val byteKey = key."
+                        "toByteArray(Table.UTF8_CHARSET.get()!!)";
+            }
+            writer += "var span = bb.getInt(vectorLocation - 4)";
+            writer += "var start = 0";
+            writer += "while (span != 0) {";
+            writer.IncrementIdentLevel();
+            writer += "var middle = span / 2";
+            writer += "val tableOffset = __indirect(vector"
+                    "Location + 4 * (start + middle), bb)";
+            if (key_field->value.type.base_type == BASE_TYPE_STRING) {
+                writer += "val comp = compareStrings(\\";
+                writer += GenOffsetGetter(key_field) + "\\";
+                writer += ", byteKey, bb)";
+            } else {
+                auto cast = CastToUsigned(key_field->value.type);
+                auto get_val = GenLookupByKey(key_field, "bb");
+                writer += "val value = " + get_val + cast;
+                writer += "val comp = value.compareTo(key)";
+            }
+            writer += "when {";
+            writer.IncrementIdentLevel();
+            writer += "comp > 0 -> span = middle";
+            writer += "comp < 0 -> {";
+            writer.IncrementIdentLevel();
+            writer += "middle++";
+            writer += "start += middle";
+            writer += "span -= middle";
+            writer.DecrementIdentLevel();
+            writer += "}"; // end comp < 0
+            writer += "else -> {";
+            writer.IncrementIdentLevel();
+            writer += "return (obj ?: {{struct_name}}()).__assign(tableOffset, bb)";
+            writer.DecrementIdentLevel();
+            writer += "}"; // end else
+            writer.DecrementIdentLevel();
+            writer += "}"; // end when
+            writer.DecrementIdentLevel();
+            writer += "}"; // end while
+            writer += "return null";
+        };
+        GenerateFun(writer, "__lookup_by_key",
+                    params.str(),
+                    Esc(struct_def.name) + "?",
+                    statements);
+    }
+
+    void GenerateFinishSizePrefixed(StructDef &struct_def,
+                                                const std::string &identifier,
+                                                CodeWriter &writer) const {
+        auto id = identifier.length() > 0  ? ", \"" + identifier + "\"" : "";
+        auto params = "builder: FlatBufferBuilder, offset: Int";
+        auto method_name = "finishSizePrefixed" + Esc(struct_def.name) + "Buffer";
+        GenerateFunOneLine(writer, method_name, params, "", [&]() {
+            writer += "builder.finishSizePrefixed(offset" + id  + ")";
+        });
+    }
+    void GenerateFinishStructBuffer(StructDef &struct_def,
+                                    const std::string &identifier,
+                                    CodeWriter &writer) const {
+        auto id = identifier.length() > 0  ? ", \"" + identifier + "\"" : "";
+        auto params = "builder: FlatBufferBuilder, offset: Int";
+        auto method_name = "finish" + Esc(struct_def.name) + "Buffer";
+        GenerateFunOneLine(writer, method_name, params, "", [&]() {
+            writer += "builder.finish(offset" + id + ")";
+        });
+    }
+
+    void GenerateEndStructMethod(StructDef &struct_def, CodeWriter &writer) const {
+        // Generate end{{TableName}}(builder: FlatBufferBuilder) method
+        auto name = "end" + Esc(struct_def.name);
+        auto params = "builder: FlatBufferBuilder";
+        auto returns = "Int";
+        auto field_vec = struct_def.fields.vec;
+
+        GenerateFun(writer, name, params, returns, [&](){
+            writer += "val o = builder.endTable()";
+            writer.IncrementIdentLevel();
+            for (auto it = field_vec.begin(); it != field_vec.end(); ++it) {
+                auto &field = **it;
+                if (field.deprecated || !field.required) {
+                    continue;
+                }
+                writer.SetValue("offset", NumToString(field.value.offset));
+                writer += "builder.required(o, {{offset}})";
+            }
+            writer.DecrementIdentLevel();
+            writer += "return o";
+        });
+    }
+
+    // Generate a method to create a vector from a Kotlin array.
+    void GenerateCreateVectorField(FieldDef &field, CodeWriter &writer) const {
+        auto vector_type = field.value.type.VectorType();
+        auto method_name = "create" + MakeCamel(Esc(field.name)) + "Vector";
+        auto params = "builder: FlatBufferBuilder, data: " +
+                GenTypeBasic(vector_type.base_type) + "Array";
+        writer.SetValue("size", NumToString(InlineSize(vector_type)));
+        writer.SetValue("align", NumToString(InlineAlignment(vector_type)));
+        writer.SetValue("root", GenMethod(vector_type));
+        writer.SetValue("cast", CastToSigned(vector_type));
+
+        GenerateFun(writer, method_name, params, "Int", [&](){
+            writer += "builder.startVector({{size}}, data.size, {{align}})";
+            writer += "for (i in data.size - 1 downTo 0) {";
+            writer.IncrementIdentLevel();
+            writer += "builder.add{{root}}(data[i]{{cast}})";
+            writer.DecrementIdentLevel();
+            writer += "}";
+            writer += "return builder.endVector()";
+        });
+    }
+
+    void GenerateStartVectorField(FieldDef &field, CodeWriter &writer) const {
+        // Generate a method to start a vector, data to be added manually
+        // after.
+        auto vector_type = field.value.type.VectorType();
+        auto params = "builder: FlatBufferBuilder, numElems: Int";
+        writer.SetValue("size", NumToString(InlineSize(vector_type)));
+        writer.SetValue("align", NumToString(InlineAlignment(vector_type)));
+
+        GenerateFunOneLine(writer,
+                           "start" + MakeCamel(Esc(field.name) + "Vector", true),
+                           params,
+                           "",
+                           [&]() {
+            writer += "builder.startVector({{size}}, numElems, {{align}})";
+        });
+    }
+
+    void GenerateAddField(std::string field_pos, FieldDef &field,
+                          CodeWriter &writer) const {
+        auto field_type = GenTypeBasic(field.value.type.base_type);
+        auto secondArg = MakeCamel(Esc(field.name), false) + ": " + field_type;
+        GenerateFunOneLine(writer, "add" + MakeCamel(Esc(field.name), true),
+                           "builder: FlatBufferBuilder, " + secondArg, "", [&](){
+            auto method = GenMethod(field.value.type);
+            writer.SetValue("field_name", MakeCamel(Esc(field.name), false));
+            writer.SetValue("method_name", method);
+            writer.SetValue("pos", field_pos);
+            writer.SetValue("default", GenFBBDefaultValue(field));
+            writer.SetValue("cast", GenFBBValueCast(field));
+
+            writer += "builder.add{{method_name}}({{pos}}, \\";
+            writer += "{{field_name}}{{cast}}, {{default}})";
+        });
+    }
+
+    static std::string ToSignedType(const Type & type) {
+        switch(type.base_type) {
+        case BASE_TYPE_UINT:
+            return GenTypeBasic(BASE_TYPE_INT);
+        case BASE_TYPE_ULONG:
+            return GenTypeBasic(BASE_TYPE_LONG);
+        case BASE_TYPE_UCHAR:
+        case BASE_TYPE_NONE:
+        case BASE_TYPE_UTYPE:
+            return GenTypeBasic(BASE_TYPE_CHAR);
+        case BASE_TYPE_USHORT:
+            return GenTypeBasic(BASE_TYPE_SHORT);
+        case BASE_TYPE_VECTOR:
+            return ToSignedType(type.VectorType());
+        default:
+            return GenTypeBasic(type.base_type);
+        }
+    }
+
+    static std::string FlexBufferBuilderCast(const std::string &method,
+                                      FieldDef &field,
+                                      bool isFirst) {
+        auto field_type = GenTypeBasic(field.value.type.base_type);
+        std::string to_type;
+        if (method == "Boolean")
+            to_type = "Boolean";
+        else if (method == "Long")
+            to_type = "Long";
+        else if (method == "Int" || method == "Offset" || method == "Struct")
+            to_type = "Int";
+        else if (method == "Byte" || method.empty())
+            to_type =  isFirst ? "Byte" : "Int";
+        else if (method == "Short")
+            to_type =  isFirst ? "Short" : "Int";
+        else if (method == "Double")
+            to_type =  "Double";
+        else if (method == "Float")
+            to_type =  isFirst ? "Float" : "Double";
+        else if (method == "UByte")
+
+        if (field_type != to_type)
+            return ".to" + to_type + "()";
+        return "";
+    }
+
+    // fun startMonster(builder: FlatBufferBuilder) = builder.startTable(11)
+    void GenerateStartStructMethod(StructDef &struct_def, CodeWriter &code) const {
+        GenerateFunOneLine(code, "start" + Esc(struct_def.name),
+                           "builder: FlatBufferBuilder", "", [&] () {
+            code += "builder.startTable("+ NumToString(struct_def.fields.vec.size()) + ")";
+        });
+    }
+
+    void GenerateTableCreator(StructDef &struct_def, CodeWriter &writer) const {
+        // Generate a method that creates a table in one go. This is only possible
+        // when the table has no struct fields, since those have to be created
+        // inline, and there's no way to do so in Java.
+        bool has_no_struct_fields = true;
+        int num_fields = 0;
+        auto fields_vec = struct_def.fields.vec;
+
+        for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
+            auto &field = **it;
+            if (field.deprecated) continue;
+            if (IsStruct(field.value.type)) {
+                has_no_struct_fields = false;
+            } else {
+                num_fields++;
+            }
+        }
+        // JVM specifications restrict default constructor params to be < 255.
+        // Longs and doubles take up 2 units, so we set the limit to be < 127.
+        if (has_no_struct_fields && num_fields && num_fields < 127) {
+            // Generate a table constructor of the form:
+            // public static int createName(FlatBufferBuilder builder, args...)
+
+            auto name = "create" + Esc(struct_def.name);
+            std::stringstream params;
+            params << "builder: FlatBufferBuilder";
+            for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
+                auto &field = **it;
+                if (field.deprecated) continue;
+                params << ", " << MakeCamel(Esc(field.name), false);
+                if (!IsScalar(field.value.type.base_type)){
+                    params << "Offset: ";
+                } else {
+                    params << ": ";
+                }
+                params << GenTypeBasic(field.value.type.base_type);
+            }
+
+            GenerateFun(writer, name, params.str(), "Int", [&]() {
+                writer.SetValue("vec_size", NumToString(fields_vec.size()));
+
+                writer += "builder.startTable({{vec_size}})";
+
+                auto sortbysize = struct_def.sortbysize;
+                auto largest = sortbysize ? sizeof(largest_scalar_t) : 1;
+                for (size_t size = largest; size; size /= 2) {
+                    for (auto it = fields_vec.rbegin(); it != fields_vec.rend();
+                         ++it) {
+                        auto &field = **it;
+                        auto base_type_size = SizeOf(field.value.type.base_type);
+                        if (!field.deprecated &&
+                                (!sortbysize || size == base_type_size)) {
+                            writer.SetValue("camel_field_name",
+                                          MakeCamel(Esc(field.name), true));
+                            writer.SetValue("field_name",
+                                          MakeCamel(Esc(field.name), false));
+
+                            writer += "add{{camel_field_name}}(builder, {{field_name}}\\";
+                            if (!IsScalar(field.value.type.base_type)){
+                                writer += "Offset\\";
+                            }
+                            writer += ")";
+                        }
+                    }
+                }
+              writer += "return end{{struct_name}}(builder)";
+            });
+        }
+
+    }
+    void GenerateBufferHasIdentifier(StructDef &struct_def,
+                                     CodeWriter &writer) const {
+        auto file_identifier = parser_.file_identifier_;
+        // Check if a buffer has the identifier.
+        if (parser_.root_struct_def_ != &struct_def || !file_identifier.length())
+            return;
+        auto name = MakeCamel(Esc(struct_def.name), false);
+        GenerateFunOneLine(writer, name + "BufferHasIdentifier",
+                           "_bb: ByteBuffer",
+                           "Boolean",
+                           [&]() {
+            writer += "__has_identifier(_bb, \"" + file_identifier + "\")";
+        });
+    }
+
+    void GenerateStructGetters(StructDef &struct_def, CodeWriter &writer) const {
+        auto fields_vec = struct_def.fields.vec;
+        FieldDef *key_field = nullptr;
+        for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
+            auto &field = **it;
+            if (field.deprecated) continue;
+            if (field.key) key_field = &field;
+
+            GenerateComment(field.doc_comment, writer, &comment_config);
+
+            auto field_name = MakeCamel(Esc(field.name), false);
+            auto field_type = GenTypeGet(field.value.type);
+            auto field_default_value = GenDefaultValue(field);
+            auto return_type = GenTypeGet(field.value.type);
+            auto bbgetter = ByteBufferGetter(field.value.type, "bb");
+            auto ucast = CastToUsigned(field);
+            auto offset_val = NumToString(field.value.offset);
+            auto offset_prefix = "val o = __offset(" + offset_val
+                                 + "); return o != 0 ? ";
+            auto value_base_type = field.value.type.base_type;
+            // Most field accessors need to retrieve and test the field offset
+            // first, this is the offset value for that:
+            writer.SetValue("offset", NumToString(field.value.offset));
+            writer.SetValue("return_type", return_type);
+            writer.SetValue("field_type", field_type);
+            writer.SetValue("field_name", field_name);
+            writer.SetValue("field_default", field_default_value);
+            writer.SetValue("bbgetter", bbgetter);
+            writer.SetValue("ucast", ucast);
+
+            auto opt_ret_type = return_type + "?";
+            // Generate the accessors that don't do object reuse.
+            if (value_base_type == BASE_TYPE_STRUCT) {
+                // Calls the accessor that takes an accessor object with a
+                // new object.
+                // val pos
+                //     get() = pos(Vec3())
+                GenerateGetterOneLine(writer, field_name, opt_ret_type, [&](){
+                    writer += "{{field_name}}({{field_type}}())";
+                });
+            } else if (value_base_type == BASE_TYPE_VECTOR &&
+                       field.value.type.element == BASE_TYPE_STRUCT) {
+                // Accessors for vectors of structs also take accessor objects,
+                // this generates a variant without that argument.
+                // ex: fun weapons(j: Int) = weapons(Weapon(), j)
+                GenerateFunOneLine(writer, field_name, "j: Int", opt_ret_type, [&](){
+                    writer += "{{field_name}}({{return_type}}(), j)";
+                });
+            }
+
+            if (IsScalar(value_base_type)) {
+                if (struct_def.fixed) {
+                    GenerateGetterOneLine(writer, field_name, return_type, [&](){
+                        writer += "{{bbgetter}}(bb_pos + {{offset}}){{ucast}}";
+                    });
+                } else {
+                    GenerateGetter(writer, field_name, return_type, [&](){
+                        writer += "val o = __offset({{offset}})";
+                        writer += "return if(o != 0) {{bbgetter}}"
+                                  "(o + bb_pos){{ucast}} else "
+                                  "{{field_default}}";
+                    });
+                }
+            } else {
+                switch (value_base_type) {
+                case BASE_TYPE_STRUCT:
+                    if (struct_def.fixed) {
+                        // create getter with object reuse
+                        // ex:
+                        // fun pos(obj: Vec3) : Vec3? = obj.__assign(bb_pos + 4, bb)
+                        // ? adds nullability annotation
+                        GenerateFunOneLine(writer,
+                                           field_name, "obj: " + field_type ,
+                                           return_type + "?", [&](){
+                            writer += "obj.__assign(bb_pos + {{offset}}, bb)";
+                        });
+                    } else {
+                        // create getter with object reuse
+                        // ex:
+                        //  fun pos(obj: Vec3) : Vec3? {
+                        //      val o = __offset(4)
+                        //      return if(o != 0) {
+                        //          obj.__assign(o + bb_pos, bb)
+                        //      else {
+                        //          null
+                        //      }
+                        //  }
+                        // ? adds nullability annotation
+                        GenerateFun(writer, field_name, "obj: " + field_type,
+                                    return_type + "?", [&](){
+                            auto fixed = field.value.type.struct_def->fixed;
+
+                            writer.SetValue("seek", Indirect("o + bb_pos", fixed));
+                            OffsetWrapper(writer,
+                                          offset_val,
+                                          [&]() { writer += "obj.__assign({{seek}}, bb)"; },
+                                          [&]() { writer += "null"; });
+                        });
+                    }
+                    break;
+                case BASE_TYPE_STRING:
+                    // create string getter
+                    // e.g.
+                    // val Name : String?
+                    //     get() = {
+                    //         val o = __offset(10)
+                    //         return if (o != 0) __string(o + bb_pos) else null
+                    //     }
+                    // ? adds nullability annotation
+                    GenerateGetter(writer, field_name, return_type + "?", [&](){
+
+                        writer += "val o = __offset({{offset}})";
+                        writer += "return if (o != 0) __string(o + bb_pos) else null";
+                    });
+                    break;
+                case BASE_TYPE_VECTOR: {
+                    // e.g.
+                    // fun inventory(j: Int) : UByte {
+                    //     val o = __offset(14)
+                    //     return if (o != 0) {
+                    //         bb.get(__vector(o) + j * 1).toUByte()
+                    //     } else {
+                    //        0
+                    //     }
+                    // }
+
+                    auto vectortype = field.value.type.VectorType();
+                    std::string params = "j: Int";
+                    std::string nullable = IsScalar(vectortype.base_type) ? ""
+                                                                          : "?";
+
+                    if (vectortype.base_type == BASE_TYPE_STRUCT ||
+                            vectortype.base_type == BASE_TYPE_UNION) {
+                        params = "obj: " + field_type + ", j: Int";
+                    }
+
+
+                    writer.SetValue("toType", "YYYYY");
+
+                    auto ret_type = return_type + nullable;
+                    GenerateFun(writer, field_name, params, ret_type, [&](){
+                        auto inline_size = NumToString(InlineSize(vectortype));
+                        auto index = "__vector(o) + j * " + inline_size;
+                        auto not_found = NotFoundReturn(field.value.type.element);
+                        auto found = "";
+                        writer.SetValue("index", index);
+                        switch(vectortype.base_type) {
+                        case BASE_TYPE_STRUCT: {
+                            bool fixed = vectortype.struct_def->fixed;
+                            writer.SetValue("index", Indirect(index, fixed));
+                            found = "obj.__assign({{index}}, bb)";
+                            break;
+                        }
+                        case BASE_TYPE_UNION:
+                            found = "{{bbgetter}}(obj, {{index}} - bb_pos){{ucast}}";
+                            break;
+                        default:
+                            found = "{{bbgetter}}({{index}}){{ucast}}";
+                        }
+                        OffsetWrapper(writer, offset_val,
+                                      [&]() { writer += found; } ,
+                                      [&]() { writer += not_found; });
+                    });
+                    break;
+                }
+                case BASE_TYPE_UNION:
+                    GenerateFun(writer, field_name, "obj: " + field_type,
+                                return_type + "?", [&](){
+                        writer += OffsetWrapperOneLine(offset_val,
+                                                       bbgetter + "(obj, o)",
+                                                       "null");
+                    });
+                    break;
+                default:
+                    FLATBUFFERS_ASSERT(0);
+                }
+            }
+
+            if (value_base_type == BASE_TYPE_VECTOR) {
+                // Generate Lenght functions for vectors
+                GenerateGetter(writer, field_name + "Length", "Int", [&](){
+                    writer += OffsetWrapperOneLine(offset_val,
+                                                   "__vector_len(o)", "0");
+                });
+
+                // See if we should generate a by-key accessor.
+                if (field.value.type.element == BASE_TYPE_STRUCT &&
+                        !field.value.type.struct_def->fixed) {
+                    auto &sd = *field.value.type.struct_def;
+                    auto &fields = sd.fields.vec;
+                    for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
+                        auto &kfield = **kit;
+                        if (kfield.key) {
+                            auto qualified_name = WrapInNameSpace(sd);
+                            auto name = MakeCamel(Esc(field.name), false) + "ByKey";
+                            auto params = "key: " + GenTypeGet(kfield.value.type);
+                            auto rtype = qualified_name + "?";
+                            GenerateFun(writer, name, params, rtype, [&] () {
+                                OffsetWrapper(writer, offset_val,
+                                [&] () {
+                                    writer += qualified_name +
+                                    ".__lookup_by_key(null, __vector(o), key, bb)";
+                                },
+                                [&] () {
+                                    writer += "null";
+                                });
+                            });
+
+                            auto param2 = "obj: " + qualified_name +
+                                    ", key: " +
+                                    GenTypeGet(kfield.value.type);
+                            GenerateFun(writer, name, param2, rtype, [&](){
+                                OffsetWrapper(writer, offset_val,
+                                [&] () {
+                                    writer += qualified_name +
+                                    ".__lookup_by_key(obj, __vector(o), key, bb)";
+                                },
+                                [&]() { writer += "null"; });
+                            });
+
+                            break;
+                        }
+                    }
+                }
+            }
+
+            if ((value_base_type == BASE_TYPE_VECTOR &&
+                 IsScalar(field.value.type.VectorType().base_type)) ||
+                    value_base_type == BASE_TYPE_STRING) {
+
+                auto end_idx = NumToString(value_base_type == BASE_TYPE_STRING
+                                           ? 1
+                                           : InlineSize(field.value.type.VectorType()));
+                // Generate a ByteBuffer accessor for strings & vectors of scalars.
+                // e.g.
+                // val inventoryByteBuffer: ByteBuffer
+                //     get =  __vector_as_bytebuffer(14, 1)
+
+                GenerateGetterOneLine(writer, field_name + "AsByteBuffer",
+                                      "ByteBuffer", [&](){
+                    writer.SetValue("end", end_idx);
+                    writer += "__vector_as_bytebuffer({{offset}}, {{end}})";
+                });
+
+                // Generate a ByteBuffer accessor for strings & vectors of scalars.
+                // e.g.
+                // fun inventoryInByteBuffer(_bb: Bytebuffer):
+                //     ByteBuffer = __vector_as_bytebuffer(_bb, 14, 1)
+                GenerateFunOneLine(writer, field_name + "InByteBuffer",
+                                   "_bb: ByteBuffer", "ByteBuffer", [&](){
+                    writer.SetValue("end", end_idx);
+                    writer += "__vector_in_bytebuffer(_bb, {{offset}}, {{end}})";
+                });
+            }
+
+            // generate object accessors if is nested_flatbuffer
+            //fun testnestedflatbufferAsMonster() : Monster?
+            //{ return testnestedflatbufferAsMonster(new Monster()); }
+
+            if (field.nested_flatbuffer) {
+                auto nested_type_name = WrapInNameSpace(*field.nested_flatbuffer);
+                auto nested_method_name =
+                        field_name + "As" +
+                        field.nested_flatbuffer->name;
+
+                GenerateGetterOneLine(writer,
+                                      nested_method_name,
+                                      nested_type_name + "?", [&](){
+                    writer += nested_method_name + "(" + nested_type_name + "())";
+                });
+
+                GenerateFun(writer,
+                            nested_method_name,
+                            "obj: " + nested_type_name,
+                            nested_type_name + "?", [&](){
+                    OffsetWrapper(writer, offset_val,
+                                  [&]() { writer += "obj.__assign(__indirect(__vector(o)), bb)"; },
+                                  [&]() { writer += "null";});
+                });
+            }
+
+            // Generate mutators for scalar fields or vectors of scalars.
+            if (parser_.opts.mutable_buffer) {
+                auto value_type = field.value.type;
+                auto underlying_type = value_base_type == BASE_TYPE_VECTOR
+                        ? value_type.VectorType()
+                        : value_type;
+                auto name = "mutate" + MakeCamel(Esc(field.name), true);
+                auto size = NumToString(InlineSize(underlying_type));
+                auto params = Esc(field.name) + ": " + GenTypeGet(underlying_type);
+                // A vector mutator also needs the index of the vector element it should
+                // mutate.
+                if (value_base_type == BASE_TYPE_VECTOR)
+                    params.insert(0, "j: Int, ");
+
+                // Boolean parameters have to be explicitly converted to byte
+                // representation.
+                auto setter_parameter = underlying_type.base_type == BASE_TYPE_BOOL
+                        ? "(if(" + Esc(field.name) + ") 1 else 0).toByte()"
+                        : Esc(field.name);
+
+                auto setter_index = value_base_type == BASE_TYPE_VECTOR
+                        ? "__vector(o) + j * " + size
+                        : (struct_def.fixed
+                           ? "bb_pos + " + offset_val
+                           : "o + bb_pos");
+                if (IsScalar(value_base_type) || (value_base_type == BASE_TYPE_VECTOR &&
+                         IsScalar(value_type.VectorType().base_type))) {
+
+                    auto statements = [&] () {
+                        writer.SetValue("bbsetter", ByteBufferSetter(underlying_type));
+                        writer.SetValue("index", setter_index);
+                        writer.SetValue("params", setter_parameter);
+                        writer.SetValue("cast", CastToSigned(field));
+                        if (struct_def.fixed) {
+                            writer += "{{bbsetter}}({{index}}, {{params}}{{cast}})";
+                        } else {
+                            OffsetWrapper(writer, offset_val, [&](){
+                                writer += "{{bbsetter}}({{index}}, {{params}}{{cast}})";
+                                writer += "true";
+                            }, [&](){ writer += "false";});
+                        }
+                    };
+
+                    if (struct_def.fixed) {
+                        GenerateFunOneLine(writer, name, params, "ByteBuffer",
+                                    statements);
+                    } else {
+                        GenerateFun(writer, name, params, "Boolean",
+                                    statements);
+                    }
+                }
+            }
+        }
+        if (struct_def.has_key && !struct_def.fixed) {
+            // Key Comparison method
+            GenerateOverrideFun(
+                        writer,
+                        "keysCompare",
+                        "o1: Int, o2: Int, _bb: ByteBuffer", "Int", [&]() {
+                if (key_field->value.type.base_type == BASE_TYPE_STRING) {
+                    writer.SetValue("offset", NumToString(key_field->value.offset));
+                    writer += " return compareStrings(__offset({{offset}}, o1, "
+                            "_bb), __offset({{offset}}, o2, _bb), _bb)";
+
+                } else {
+                    auto getter1 = GenLookupByKey(key_field, "_bb", "o1");
+                    auto getter2 = GenLookupByKey(key_field, "_bb", "o2");
+                    writer += "val val_1 = " + getter1;
+                    writer += "val val_2 = " + getter2;
+                    writer += "return (val_1 - val_2).sign";
+                }
+            });
+        }
+    }
+
+    static std::string CastToUsigned(const FieldDef &field) {
+        return CastToUsigned(field.value.type);
+    }
+
+    static std::string CastToUsigned(const Type type) {
+        switch (type.base_type) {
+        case BASE_TYPE_UINT:
+            return ".toUInt()";
+        case BASE_TYPE_UCHAR:
+        case BASE_TYPE_UTYPE:
+            return ".toUByte()";
+        case BASE_TYPE_USHORT:
+            return ".toUShort()";
+        case BASE_TYPE_ULONG:
+            return ".toULong()";
+        case BASE_TYPE_VECTOR:
+            return CastToUsigned(type.VectorType());
+        default:
+            return "";
+        }
+    }
+
+    static std::string CastToSigned(const FieldDef &field) {
+        return CastToSigned(field.value.type);
+    }
+
+    static std::string CastToSigned(const Type type) {
+        switch (type.base_type) {
+        case BASE_TYPE_UINT:
+            return ".toInt()";
+        case BASE_TYPE_UCHAR:
+        case BASE_TYPE_UTYPE:
+            return ".toByte()";
+        case BASE_TYPE_USHORT:
+            return ".toShort()";
+        case BASE_TYPE_ULONG:
+            return ".toLong()";
+        case BASE_TYPE_VECTOR:
+            return CastToSigned(type.VectorType());
+        default:
+            return "";
+        }
+    }
+
+    static std::string LiteralSuffix(const BaseType type) {
+        switch (type) {
+        case BASE_TYPE_UINT:
+        case BASE_TYPE_UCHAR:
+        case BASE_TYPE_UTYPE:
+        case BASE_TYPE_USHORT:
+            return "u";
+        case BASE_TYPE_ULONG:
+            return "UL";
+        case BASE_TYPE_LONG:
+            return "L";
+        default:
+            return "";
+        }
+    }
+
+    void GenerateCompanionObject(CodeWriter &code,
+                                 const std::function<void()> &callback) const {
+        code += "companion object {";
+        code.IncrementIdentLevel();
+        callback();
+        code.DecrementIdentLevel();
+        code += "}";
+    }
+
+    // Generate a documentation comment, if available.
+    void GenerateComment(const std::vector<std::string> &dc, CodeWriter &writer,
+                    const CommentConfig *config) const {
+      if (dc.begin() == dc.end()) {
+        // Don't output empty comment blocks with 0 lines of comment content.
+        return;
+      }
+
+      if (config != nullptr && config->first_line != nullptr) {
+        writer += std::string(config->first_line);
+      }
+      std::string line_prefix =
+          ((config != nullptr && config->content_line_prefix != nullptr)
+               ? config->content_line_prefix
+               : "///");
+      for (auto it = dc.begin(); it != dc.end(); ++it) {
+        writer += line_prefix + *it;
+      }
+      if (config != nullptr && config->last_line != nullptr) {
+        writer += std::string(config->last_line);
+      }
+    }
+
+    static void GenerateGetRootAsAccessors(const std::string &struct_name,
+                                           CodeWriter &writer) {
+        // Generate a special accessor for the table that when used as the root
+        // ex: fun getRootAsMonster(_bb: ByteBuffer): Monster {...}
+        writer.SetValue("gr_name", struct_name);
+        writer.SetValue("gr_method", "getRootAs" + struct_name);
+
+        // create convenience method that doesn't require an existing object
+        writer += "fun {{gr_method}}(_bb: ByteBuffer): {{gr_name}} = \\";
+        writer += "{{gr_method}}(_bb, {{gr_name}}())";
+
+        // create method that allows object reuse
+        // ex: fun Monster getRootAsMonster(_bb: ByteBuffer, obj: Monster) {...}
+        writer += "fun {{gr_method}}"
+                 "(_bb: ByteBuffer, obj: {{gr_name}}): {{gr_name}} {";
+        writer.IncrementIdentLevel();
+        writer += "_bb.order(ByteOrder.LITTLE_ENDIAN)";
+        writer += "return (obj.__assign(_bb.getInt(_bb.position())"
+                 " + _bb.position(), _bb))";
+        writer.DecrementIdentLevel();
+        writer += "}";
+    }
+
+    static void GenerateStaticConstructor(const StructDef &struct_def,
+                                          CodeWriter &code) {
+        // create a struct constructor function
+        auto params = StructConstructorParams(struct_def);
+        GenerateFun(code, "create" + Esc(struct_def.name), params, "Int", [&](){
+            GenStructBody(struct_def, code, "");
+            code += "return builder.offset()";
+        });
+    }
+
+    static std::string StructConstructorParams(const StructDef &struct_def,
+                                               const std::string &prefix = "") {
+        //builder: FlatBufferBuilder
+        std::stringstream out;
+        auto field_vec = struct_def.fields.vec;
+        if (prefix.empty()) {
+            out << "builder: FlatBufferBuilder";
+        }
+        for (auto it = field_vec.begin(); it != field_vec.end(); ++it) {
+            auto &field = **it;
+            if (IsStruct(field.value.type)) {
+                // Generate arguments for a struct inside a struct. To ensure
+                // names don't clash, and to make it obvious these arguments are
+                // constructing a nested struct, prefix the name with the field
+                // name.
+                out << StructConstructorParams(*field.value.type.struct_def,
+                                              prefix + (Esc(field.name) + "_"));
+            } else {
+                out << ", " << prefix << MakeCamel(Esc(field.name), false)
+                    << ": "
+                    << GenTypeBasic(field.value.type.base_type);
+            }
+        }
+        return out.str();
+    }
+
+    static void GeneratePropertyOneLine(CodeWriter &writer,
+                               const std::string &name,
+                               const std::string &type,
+                               const std::function<void()> &body) {
+        // Generates Kotlin getter for properties
+        // e.g.:
+        // val prop: Mytype = x
+        writer.SetValue("_name", name);
+        writer.SetValue("_type", type);
+        writer += "val {{_name}} : {{_type}} = \\";
+        body();
+    }
+    static void GenerateGetterOneLine(CodeWriter &writer,
+                               const std::string &name,
+                               const std::string &type,
+                               const std::function<void()> &body) {
+        // Generates Kotlin getter for properties
+        // e.g.:
+        // val prop: Mytype get() = x
+        writer.SetValue("_name", name);
+        writer.SetValue("_type", type);
+        writer += "val {{_name}} : {{_type}} get() = \\";
+        body();
+    }
+
+    static void GenerateGetter(CodeWriter &writer,
+                               const std::string &name,
+                               const std::string &type,
+                               const std::function<void()> &body) {
+        // Generates Kotlin getter for properties
+        // e.g.:
+        // val prop: Mytype
+        //     get() = {
+        //       return x
+        //     }
+        writer.SetValue("name", name);
+        writer.SetValue("type", type);
+        writer += "val {{name}} : {{type}}";
+        writer.IncrementIdentLevel();
+        writer += "get() {";
+        writer.IncrementIdentLevel();
+        body();
+        writer.DecrementIdentLevel();
+        writer += "}";
+        writer.DecrementIdentLevel();
+    }
+
+    static void GenerateFun(CodeWriter &writer,
+                            const std::string &name,
+                            const std::string &params,
+                            const std::string &returnType,
+                            const std::function<void()> &body) {
+        // Generates Kotlin function
+        // e.g.:
+        // fun path(j: Int): Vec3 {
+        //     return path(Vec3(), j)
+        // }
+        auto noreturn = returnType.empty();
+        writer.SetValue("name", name);
+        writer.SetValue("params", params);
+        writer.SetValue("return_type", noreturn ? "" : ": " + returnType);
+        writer += "fun {{name}}({{params}}) {{return_type}} {";
+        writer.IncrementIdentLevel();
+        body();
+        writer.DecrementIdentLevel();
+        writer += "}";
+    }
+
+    static void GenerateFunOneLine(CodeWriter &writer,
+                                   const std::string &name,
+                                   const std::string &params,
+                                   const std::string &returnType,
+                                   const std::function<void()> &body) {
+        // Generates Kotlin function
+        // e.g.:
+        // fun path(j: Int): Vec3 = return path(Vec3(), j)
+        writer.SetValue("name", name);
+        writer.SetValue("params", params);
+        writer.SetValue("return_type_p", returnType.empty() ? "" :
+                                                          " : " + returnType);
+        writer += "fun {{name}}({{params}}){{return_type_p}} = \\";
+        body();
+    }
+
+    static void GenerateOverrideFun(CodeWriter &writer,
+                                   const std::string &name,
+                                   const std::string &params,
+                                   const std::string &returnType,
+                                   const std::function<void()> &body) {
+        // Generates Kotlin function
+        // e.g.:
+        // override fun path(j: Int): Vec3 = return path(Vec3(), j)
+        writer += "override \\";
+        GenerateFun(writer, name, params, returnType, body);
+    }
+
+    static void GenerateOverrideFunOneLine(CodeWriter &writer,
+                                   const std::string &name,
+                                   const std::string &params,
+                                   const std::string &returnType,
+                                   const std::string &statement) {
+        // Generates Kotlin function
+        // e.g.:
+        // override fun path(j: Int): Vec3 = return path(Vec3(), j)
+        writer.SetValue("name", name);
+        writer.SetValue("params", params);
+        writer.SetValue("return_type", returnType.empty() ? "" :
+                                                          " : " + returnType);
+        writer += "override fun {{name}}({{params}}){{return_type}} = \\";
+        writer += statement;
+    }
+
+    static std::string OffsetWrapperOneLine(const std::string &offset,
+                                            const std::string &found,
+                                            const std::string &not_found) {
+        return "val o = __offset(" + offset + "); return if (o != 0) " + found +
+                " else " + not_found;
+    }
+
+    static void OffsetWrapper(CodeWriter &code,
+                       const std::string &offset,
+                       const std::function<void()> &found,
+                       const std::function<void()> &not_found) {
+        code += "val o = __offset(" + offset + ")";
+        code +="return if (o != 0) {";
+        code.IncrementIdentLevel();
+        found();
+        code.DecrementIdentLevel();
+        code += "} else {";
+        code.IncrementIdentLevel();
+        not_found();
+        code.DecrementIdentLevel();
+        code += "}";
+    }
+
+    static std::string Indirect(const std::string &index, bool fixed) {
+        // We apply __indirect() and struct is not fixed.
+        if (!fixed)
+            return "__indirect(" + index + ")";
+        return index;
+    }
+
+    static std::string NotFoundReturn(BaseType el) {
+        switch (el) {
+        case BASE_TYPE_FLOAT:
+           return "0.0f";
+         case BASE_TYPE_DOUBLE:
+            return "0.0";
+        case BASE_TYPE_BOOL:
+            return "false";
+        case BASE_TYPE_LONG:
+        case BASE_TYPE_INT:
+        case BASE_TYPE_CHAR:
+        case BASE_TYPE_SHORT:
+            return "0";
+        case BASE_TYPE_UINT:
+        case BASE_TYPE_UCHAR:
+        case BASE_TYPE_USHORT:
+        case BASE_TYPE_UTYPE:
+            return "0u";
+        case BASE_TYPE_ULONG:
+            return "0uL";
+        default:
+            return "null";
+        }
+    }
+
+    // This tracks the current namespace used to determine if a type need to be
+    // prefixed by its namespace
+    const Namespace *cur_name_space_;
+};
+}  // namespace kotlin
+
+bool GenerateKotlin(const Parser &parser, const std::string &path,
+                    const std::string &file_name) {
+    kotlin::KotlinGenerator generator(parser, path, file_name);
+    return generator.generate();
+}
+}  // namespace flatbuffers
diff --git a/src/idl_gen_lobster.cpp b/src/idl_gen_lobster.cpp
new file mode 100644
index 0000000..ef9e474
--- /dev/null
+++ b/src/idl_gen_lobster.cpp
@@ -0,0 +1,383 @@
+/*
+ * Copyright 2018 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <unordered_set>
+
+#include "flatbuffers/code_generators.h"
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+namespace flatbuffers {
+namespace lobster {
+
+class LobsterGenerator : public BaseGenerator {
+ public:
+ LobsterGenerator(const Parser &parser, const std::string &path,
+                  const std::string &file_name)
+      : BaseGenerator(parser, path, file_name, "" /* not used */, "_") {
+    static const char * const keywords[] = {
+      "nil", "true", "false", "return", "struct", "class", "import", "int",
+      "float", "string", "any", "def", "is", "from", "program", "private",
+      "coroutine", "resource", "enum", "typeof", "var", "let", "pakfile",
+      "switch", "case", "default", "namespace", "not", "and", "or", "bool",
+    };
+    keywords_.insert(std::begin(keywords), std::end(keywords));
+  }
+
+  std::string EscapeKeyword(const std::string &name) const {
+    return keywords_.find(name) == keywords_.end() ? name : name + "_";
+  }
+
+  std::string NormalizedName(const Definition &definition) const {
+    return EscapeKeyword(definition.name);
+  }
+
+  std::string NormalizedName(const EnumVal &ev) const {
+    return EscapeKeyword(ev.name);
+  }
+
+  std::string NamespacedName(const Definition &def) {
+    return WrapInNameSpace(def.defined_namespace, NormalizedName(def));
+  }
+
+  std::string GenTypeName(const Type &type) {
+    auto bits = NumToString(SizeOf(type.base_type) * 8);
+    if (IsInteger(type.base_type)) return "int" + bits;
+    if (IsFloat(type.base_type)) return "float" + bits;
+    if (type.base_type == BASE_TYPE_STRING) return "string";
+    if (type.base_type == BASE_TYPE_STRUCT) return "table";
+    return "none";
+  }
+
+  std::string LobsterType(const Type &type) {
+    if (IsFloat(type.base_type)) return "float";
+    if (IsScalar(type.base_type) && type.enum_def) return NormalizedName(*type.enum_def);
+    if (!IsScalar(type.base_type)) return "flatbuffers_offset";
+    return "int";
+  }
+
+  // Returns the method name for use with add/put calls.
+  std::string GenMethod(const Type &type) {
+    return IsScalar(type.base_type)
+      ? MakeCamel(GenTypeBasic(type))
+      : (IsStruct(type) ? "Struct" : "UOffsetTRelative");
+  }
+
+  // This uses Python names for now..
+  std::string GenTypeBasic(const Type &type) {
+    static const char *ctypename[] = {
+      // clang-format off
+      #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+        CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
+        #PTYPE,
+      FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+      #undef FLATBUFFERS_TD
+      // clang-format on
+    };
+    return ctypename[type.base_type];
+  }
+
+  // Generate a struct field, conditioned on its child type(s).
+  void GenStructAccessor(const StructDef &struct_def,
+                         const FieldDef &field, std::string *code_ptr) {
+    GenComment(field.doc_comment, code_ptr, nullptr, "    ");
+    std::string &code = *code_ptr;
+    auto offsets = NumToString(field.value.offset);
+    auto def = "    def " + NormalizedName(field);
+    if (IsScalar(field.value.type.base_type)) {
+      std::string acc;
+      if (struct_def.fixed) {
+        acc = "buf_.read_" + GenTypeName(field.value.type) +
+              "_le(pos_ + " + offsets + ")";
+
+      } else {
+        acc = "buf_.flatbuffers_field_" +
+              GenTypeName(field.value.type) + "(pos_, " + offsets + ", " +
+              field.value.constant + ")";
+      }
+      if (field.value.type.enum_def)
+        acc = NormalizedName(*field.value.type.enum_def) + "(" + acc + ")";
+      code += def + "():\n        return " + acc + "\n";
+      return;
+    }
+    switch (field.value.type.base_type) {
+      case BASE_TYPE_STRUCT: {
+        auto name = NamespacedName(*field.value.type.struct_def);
+        code += def + "():\n        ";
+        if (struct_def.fixed) {
+          code += "return " + name + "{ buf_, pos_ + " + offsets + " }\n";
+        } else {
+          code += std::string("let o = buf_.flatbuffers_field_") +
+                  (field.value.type.struct_def->fixed ? "struct" : "table") +
+                  "(pos_, " + offsets + ")\n        return if o: " + name +
+                  " { buf_, o } else: nil\n";
+        }
+        break;
+      }
+      case BASE_TYPE_STRING:
+        code += def + "():\n        return buf_.flatbuffers_field_string(pos_, " +
+                offsets + ")\n";
+        break;
+      case BASE_TYPE_VECTOR: {
+        auto vectortype = field.value.type.VectorType();
+        code += def + "(i:int):\n        return ";
+        if (vectortype.base_type == BASE_TYPE_STRUCT) {
+          auto start = "buf_.flatbuffers_field_vector(pos_, " + offsets +
+                       ") + i * " + NumToString(InlineSize(vectortype));
+          if (!(vectortype.struct_def->fixed)) {
+            start = "buf_.flatbuffers_indirect(" + start + ")";
+          }
+          code += NamespacedName(*field.value.type.struct_def) + " { buf_, " +
+                  start + " }\n";
+        } else {
+          if (vectortype.base_type == BASE_TYPE_STRING)
+            code += "buf_.flatbuffers_string";
+          else
+            code += "buf_.read_" + GenTypeName(vectortype) + "_le";
+          code += "(buf_.flatbuffers_field_vector(pos_, " + offsets +
+                  ") + i * " + NumToString(InlineSize(vectortype)) + ")\n";
+        }
+        break;
+      }
+      case BASE_TYPE_UNION: {
+        for (auto it = field.value.type.enum_def->Vals().begin();
+             it != field.value.type.enum_def->Vals().end(); ++it) {
+          auto &ev = **it;
+          if (ev.IsNonZero()) {
+            code += def + "_as_" + ev.name + "():\n        return " +
+                    NamespacedName(*ev.union_type.struct_def) +
+                    " { buf_, buf_.flatbuffers_field_table(pos_, " + offsets +
+                    ") }\n";
+          }
+        }
+        break;
+      }
+      default: FLATBUFFERS_ASSERT(0);
+    }
+    if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+      code += def +
+              "_length():\n        return buf_.flatbuffers_field_vector_len(pos_, " +
+              offsets + ")\n";
+    }
+  }
+
+  // Generate table constructors, conditioned on its members' types.
+  void GenTableBuilders(const StructDef &struct_def,
+                        std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "struct " + NormalizedName(struct_def) +
+            "Builder:\n    b_:flatbuffers_builder\n";
+    code += "    def start():\n        b_.StartObject(" +
+            NumToString(struct_def.fields.vec.size()) + ")\n        return this\n";
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+      auto offset = it - struct_def.fields.vec.begin();
+      code += "    def add_" + NormalizedName(field) + "(" +
+              NormalizedName(field) + ":" + LobsterType(field.value.type) +
+              "):\n        b_.Prepend" + GenMethod(field.value.type) + "Slot(" +
+              NumToString(offset) + ", " + NormalizedName(field);
+      if (IsScalar(field.value.type.base_type))
+        code += ", " + field.value.constant;
+      code += ")\n        return this\n";
+    }
+    code += "    def end():\n        return b_.EndObject()\n\n";
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+      if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+        code += "def " + NormalizedName(struct_def) + "Start" +
+                MakeCamel(NormalizedName(field)) +
+                "Vector(b_:flatbuffers_builder, n_:int):\n    b_.StartVector(";
+        auto vector_type = field.value.type.VectorType();
+        auto alignment = InlineAlignment(vector_type);
+        auto elem_size = InlineSize(vector_type);
+        code += NumToString(elem_size) + ", n_, " + NumToString(alignment) +
+                ")\n";
+        if (vector_type.base_type != BASE_TYPE_STRUCT ||
+            !vector_type.struct_def->fixed) {
+          code += "def " + NormalizedName(struct_def) + "Create" +
+                  MakeCamel(NormalizedName(field)) +
+                  "Vector(b_:flatbuffers_builder, v_:[" +
+                  LobsterType(vector_type) + "]):\n    b_.StartVector(" +
+                  NumToString(elem_size) + ", v_.length, " +
+                  NumToString(alignment) +
+                  ")\n    reverse(v_) e_: b_.Prepend" +
+                  GenMethod(vector_type) +
+                  "(e_)\n    return b_.EndVector(v_.length)\n";
+        }
+        code += "\n";
+      }
+    }
+  }
+
+  void GenStructPreDecl(const StructDef &struct_def, std::string *code_ptr) {
+    if (struct_def.generated) return;
+    std::string &code = *code_ptr;
+    CheckNameSpace(struct_def, &code);
+    code += "class " + NormalizedName(struct_def) + "\n\n";
+  }
+
+  // Generate struct or table methods.
+  void GenStruct(const StructDef &struct_def, std::string *code_ptr) {
+    if (struct_def.generated) return;
+    std::string &code = *code_ptr;
+    CheckNameSpace(struct_def, &code);
+    GenComment(struct_def.doc_comment, code_ptr, nullptr, "");
+    code += "class " + NormalizedName(struct_def) + " : flatbuffers_handle\n";
+    for (auto it = struct_def.fields.vec.begin();
+        it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+      GenStructAccessor(struct_def, field, code_ptr);
+    }
+    code += "\n";
+    if (!struct_def.fixed) {
+      // Generate a special accessor for the table that has been declared as
+      // the root type.
+      code += "def GetRootAs" + NormalizedName(struct_def) + "(buf:string): return " +
+              NormalizedName(struct_def) +
+              " { buf, buf.flatbuffers_indirect(0) }\n\n";
+    }
+    if (struct_def.fixed) {
+      // create a struct constructor function
+      GenStructBuilder(struct_def, code_ptr);
+    } else {
+      // Create a set of functions that allow table construction.
+      GenTableBuilders(struct_def, code_ptr);
+    }
+  }
+
+  // Generate enum declarations.
+  void GenEnum(const EnumDef &enum_def, std::string *code_ptr) {
+    if (enum_def.generated) return;
+    std::string &code = *code_ptr;
+    CheckNameSpace(enum_def, &code);
+    GenComment(enum_def.doc_comment, code_ptr, nullptr, "");
+    code += "enum " + NormalizedName(enum_def) + ":\n";
+    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) + " = " +
+              enum_def.ToString(ev) + "\n";
+    }
+    code += "\n";
+  }
+
+  // Recursively generate arguments for a constructor, to deal with nested
+  // structs.
+  void StructBuilderArgs(const StructDef &struct_def,
+                         const char *nameprefix, std::string *code_ptr) {
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (IsStruct(field.value.type)) {
+        // Generate arguments for a struct inside a struct. To ensure names
+        // don't clash, and to make it obvious these arguments are constructing
+        // a nested struct, prefix the name with the field name.
+        StructBuilderArgs(*field.value.type.struct_def,
+          (nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr);
+      } else {
+        std::string &code = *code_ptr;
+        code += ", " + (nameprefix + NormalizedName(field)) + ":" +
+                LobsterType(field.value.type);
+      }
+    }
+  }
+
+  // Recursively generate struct construction statements and instert manual
+  // padding.
+  void StructBuilderBody(const StructDef &struct_def,
+                         const char *nameprefix, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "    b_.Prep(" + NumToString(struct_def.minalign) + ", " +
+            NumToString(struct_def.bytesize) + ")\n";
+    for (auto it = struct_def.fields.vec.rbegin();
+         it != struct_def.fields.vec.rend(); ++it) {
+      auto &field = **it;
+      if (field.padding)
+        code += "    b_.Pad(" + NumToString(field.padding) + ")\n";
+      if (IsStruct(field.value.type)) {
+        StructBuilderBody(*field.value.type.struct_def,
+          (nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr);
+      } else {
+        code += "    b_.Prepend" + GenMethod(field.value.type) + "(" +
+                nameprefix + NormalizedName(field) + ")\n";
+      }
+    }
+  }
+
+  // Create a struct with a builder and the struct's arguments.
+  void GenStructBuilder(const StructDef &struct_def,
+                              std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "def Create" + NormalizedName(struct_def) +
+            "(b_:flatbuffers_builder";
+    StructBuilderArgs(struct_def, "", code_ptr);
+    code += "):\n";
+    StructBuilderBody(struct_def, "", code_ptr);
+    code += "    return b_.Offset()\n\n";
+  }
+
+  void CheckNameSpace(const Definition &def, std::string *code_ptr) {
+    auto ns = GetNameSpace(def);
+    if (ns == current_namespace_) return;
+    current_namespace_ = ns;
+    std::string &code = *code_ptr;
+    code += "namespace " + ns + "\n\n";
+  }
+
+  bool generate() {
+    std::string code;
+    code += std::string("// ") + FlatBuffersGeneratedWarning() +
+            "\nimport flatbuffers\n\n";
+    for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
+         ++it) {
+      auto &enum_def = **it;
+      GenEnum(enum_def, &code);
+    }
+    for (auto it = parser_.structs_.vec.begin();
+         it != parser_.structs_.vec.end(); ++it) {
+      auto &struct_def = **it;
+      GenStructPreDecl(struct_def, &code);
+    }
+    for (auto it = parser_.structs_.vec.begin();
+         it != parser_.structs_.vec.end(); ++it) {
+      auto &struct_def = **it;
+      GenStruct(struct_def, &code);
+    }
+    return SaveFile((path_ + file_name_ + "_generated.lobster").c_str(),
+                    code, false);
+  }
+
+ private:
+  std::unordered_set<std::string> keywords_;
+  std::string current_namespace_;
+};
+
+}  // namespace lobster
+
+bool GenerateLobster(const Parser &parser, const std::string &path,
+                    const std::string &file_name) {
+  lobster::LobsterGenerator generator(parser, path, file_name);
+  return generator.generate();
+}
+
+}  // namespace flatbuffers
diff --git a/src/idl_gen_lua.cpp b/src/idl_gen_lua.cpp
new file mode 100644
index 0000000..10df231
--- /dev/null
+++ b/src/idl_gen_lua.cpp
@@ -0,0 +1,731 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ // independent from idl_parser, since this code is not needed for most clients
+
+#include <string>
+
+#include "flatbuffers/code_generators.h"
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+#include <unordered_set>
+
+namespace flatbuffers {
+namespace lua {
+
+  // Hardcode spaces per indentation.
+  const CommentConfig def_comment = { nullptr, "--", nullptr };
+  const char * Indent = "    ";
+  const char * Comment = "-- ";
+  const char * End = "end\n";
+  const char * EndFunc = "end\n";
+  const char * SelfData = "self.view";
+  const char * SelfDataPos = "self.view.pos";
+  const char * SelfDataBytes = "self.view.bytes";
+
+  class LuaGenerator : public BaseGenerator {
+  public:
+    LuaGenerator(const Parser &parser, const std::string &path,
+      const std::string &file_name)
+      : BaseGenerator(parser, path, file_name, "" /* not used */,
+        "" /* not used */) {
+      static const char * const keywords[] = {
+        "and",
+        "break",
+        "do",
+        "else",
+        "elseif",
+        "end",
+        "false",
+        "for",
+        "function",
+        "goto",
+        "if",
+        "in",
+        "local",
+        "nil",
+        "not",
+        "or",
+        "repeat",
+        "return",
+        "then",
+        "true",
+        "until",
+        "while"
+      };
+      keywords_.insert(std::begin(keywords), std::end(keywords));
+    }
+
+    // Most field accessors need to retrieve and test the field offset first,
+    // this is the prefix code for that.
+    std::string OffsetPrefix(const FieldDef &field) {
+      return std::string(Indent) +
+        "local o = " + SelfData + ":Offset(" + NumToString(field.value.offset) + ")\n" +
+        Indent + "if o ~= 0 then\n";
+    }
+
+    // Begin a class declaration.
+    void BeginClass(const StructDef &struct_def, std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      code += "local " + NormalizedName(struct_def) + " = {} -- the module\n";
+      code += "local " + NormalizedMetaName(struct_def) + " = {} -- the class metatable\n";
+      code += "\n";
+    }
+
+    // Begin enum code with a class declaration.
+    void BeginEnum(const std::string &class_name, std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      code += "local " + class_name + " = {\n";
+    }
+
+    std::string EscapeKeyword(const std::string &name) const {
+      return keywords_.find(name) == keywords_.end() ? name : "_" + name;
+    }
+
+    std::string NormalizedName(const Definition &definition) const {
+      return EscapeKeyword(definition.name);
+    }
+
+    std::string NormalizedName(const EnumVal &ev) const {
+      return EscapeKeyword(ev.name);
+    }
+
+    std::string NormalizedMetaName(const Definition &definition) const {
+      return EscapeKeyword(definition.name) + "_mt";
+    }
+
+    // A single enum member.
+    void EnumMember(const EnumDef &enum_def, const EnumVal &ev, std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      code += std::string(Indent) + NormalizedName(ev) + " = " +
+              enum_def.ToString(ev) + ",\n";
+    }
+
+    // End enum code.
+    void EndEnum(std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      code += "}\n";
+    }
+
+    void GenerateNewObjectPrototype(const StructDef &struct_def,
+      std::string *code_ptr) {
+      std::string &code = *code_ptr;
+
+      code += "function " + NormalizedName(struct_def) + ".New()\n";
+      code += std::string(Indent) + "local o = {}\n";
+      code += std::string(Indent) + "setmetatable(o, {__index = " + NormalizedMetaName(struct_def) + "})\n";
+      code += std::string(Indent) + "return o\n";
+      code += EndFunc;
+    }
+
+    // Initialize a new struct or table from existing data.
+    void NewRootTypeFromBuffer(const StructDef &struct_def,
+      std::string *code_ptr) {
+      std::string &code = *code_ptr;
+
+      code += "function " + NormalizedName(struct_def) + ".GetRootAs" + NormalizedName(struct_def) + "(buf, offset)\n";
+      code += std::string(Indent) + "local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)\n";
+      code += std::string(Indent) + "local o = " + NormalizedName(struct_def) + ".New()\n";
+      code += std::string(Indent) + "o:Init(buf, n + offset)\n";
+      code += std::string(Indent) + "return o\n";
+      code += EndFunc;
+    }
+
+    // Initialize an existing object with other data, to avoid an allocation.
+    void InitializeExisting(const StructDef &struct_def,
+      std::string *code_ptr) {
+      std::string &code = *code_ptr;
+
+      GenReceiver(struct_def, code_ptr);
+      code += "Init(buf, pos)\n";
+      code += std::string(Indent) + SelfData + " = flatbuffers.view.New(buf, pos)\n";
+      code += EndFunc;
+    }
+
+    // Get the length of a vector.
+    void GetVectorLen(const StructDef &struct_def, const FieldDef &field,
+      std::string *code_ptr) {
+      std::string &code = *code_ptr;
+
+      GenReceiver(struct_def, code_ptr);
+      code += MakeCamel(NormalizedName(field)) + "Length()\n";
+      code += OffsetPrefix(field);
+      code += std::string(Indent) + Indent + "return " + SelfData + ":VectorLen(o)\n";
+      code += std::string(Indent) + End;
+      code += std::string(Indent) + "return 0\n";
+      code += EndFunc;
+    }
+
+    // Get the value of a struct's scalar.
+    void GetScalarFieldOfStruct(const StructDef &struct_def,
+      const FieldDef &field,
+      std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      std::string getter = GenGetter(field.value.type);
+      GenReceiver(struct_def, code_ptr);
+      code += MakeCamel(NormalizedName(field));
+      code += "()\n";
+      code += std::string(Indent) + "return " + getter;
+      code += std::string(SelfDataPos) + " + " + NumToString(field.value.offset) + ")\n";
+      code += EndFunc;
+    }
+
+    // Get the value of a table's scalar.
+    void GetScalarFieldOfTable(const StructDef &struct_def,
+      const FieldDef &field,
+      std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      std::string getter = GenGetter(field.value.type);
+      GenReceiver(struct_def, code_ptr);
+      code += MakeCamel(NormalizedName(field));
+      code += "()\n";
+      code += OffsetPrefix(field);
+      getter += std::string("o + ") + SelfDataPos + ")";
+      auto is_bool = field.value.type.base_type == BASE_TYPE_BOOL;
+      if (is_bool) {
+        getter = "(" + getter + " ~= 0)";
+      }
+      code += std::string(Indent) + Indent + "return " + getter + "\n";
+      code += std::string(Indent) + End;
+      std::string default_value;
+      if (is_bool) {
+        default_value = field.value.constant == "0" ? "false" : "true";
+      }
+      else {
+        default_value = field.value.constant;
+      }
+      code += std::string(Indent) + "return " + default_value + "\n";
+      code += EndFunc;
+    }
+
+    // Get a struct by initializing an existing struct.
+    // Specific to Struct.
+    void GetStructFieldOfStruct(const StructDef &struct_def,
+      const FieldDef &field,
+      std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      GenReceiver(struct_def, code_ptr);
+      code += MakeCamel(NormalizedName(field));
+      code += "(obj)\n";
+      code += std::string(Indent) + "obj:Init(" + SelfDataBytes + ", " + SelfDataPos + " + ";
+      code += NumToString(field.value.offset) + ")\n";
+      code += std::string(Indent) + "return obj\n";
+      code += EndFunc;
+    }
+
+    // Get a struct by initializing an existing struct.
+    // Specific to Table.
+    void GetStructFieldOfTable(const StructDef &struct_def,
+      const FieldDef &field,
+      std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      GenReceiver(struct_def, code_ptr);
+      code += MakeCamel(NormalizedName(field));
+      code += "()\n";
+      code += OffsetPrefix(field);
+      if (field.value.type.struct_def->fixed) {
+        code += std::string(Indent) + Indent + "local x = o + " + SelfDataPos + "\n";
+      }
+      else {
+        code += std::string(Indent) + Indent + "local x = " + SelfData + ":Indirect(o + " + SelfDataPos + ")\n";
+      }
+      code += std::string(Indent) + Indent + "local obj = require('" + TypeNameWithNamespace(field) + "').New()\n";
+      code += std::string(Indent) + Indent + "obj:Init(" + SelfDataBytes + ", x)\n";
+      code += std::string(Indent) + Indent + "return obj\n";
+      code += std::string(Indent) + End;
+      code += EndFunc;
+    }
+
+    // Get the value of a string.
+    void GetStringField(const StructDef &struct_def, const FieldDef &field,
+      std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      GenReceiver(struct_def, code_ptr);
+      code += MakeCamel(NormalizedName(field));
+      code += "()\n";
+      code += OffsetPrefix(field);
+      code += std::string(Indent) + Indent + "return " + GenGetter(field.value.type);
+      code += std::string("o + ") + SelfDataPos + ")\n";
+      code += std::string(Indent) + End;
+      code += EndFunc;
+    }
+
+    // Get the value of a union from an object.
+    void GetUnionField(const StructDef &struct_def, const FieldDef &field,
+      std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      GenReceiver(struct_def, code_ptr);
+      code += MakeCamel(NormalizedName(field)) + "()\n";
+      code += OffsetPrefix(field);
+
+      // TODO(rw): this works and is not the good way to it:
+      //bool is_native_table = TypeName(field) == "*flatbuffers.Table";
+      //if (is_native_table) {
+      //  code += std::string(Indent) + Indent + "from flatbuffers.table import Table\n";
+      //} else {
+      //  code += std::string(Indent) + Indent +
+      //  code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n";
+      //}
+      code += std::string(Indent) + Indent + "local obj = flatbuffers.view.New(require('flatbuffers.binaryarray').New(0), 0)\n";
+      code += std::string(Indent) + Indent + GenGetter(field.value.type) + "obj, o)\n";
+      code += std::string(Indent) + Indent + "return obj\n";
+      code += std::string(Indent) + End;
+      code += EndFunc;
+    }
+
+    // Get the value of a vector's struct member.
+    void GetMemberOfVectorOfStruct(const StructDef &struct_def,
+      const FieldDef &field,
+      std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      auto vectortype = field.value.type.VectorType();
+
+      GenReceiver(struct_def, code_ptr);
+      code += MakeCamel(NormalizedName(field));
+      code += "(j)\n";
+      code += OffsetPrefix(field);
+      code += std::string(Indent) + Indent + "local x = " + SelfData + ":Vector(o)\n";
+      code += std::string(Indent) + Indent + "x = x + ((j-1) * ";
+      code += NumToString(InlineSize(vectortype)) + ")\n";
+      if (!(vectortype.struct_def->fixed)) {
+        code += std::string(Indent) + Indent + "x = " + SelfData + ":Indirect(x)\n";
+      }
+      code += std::string(Indent) + Indent + "local obj = require('" + TypeNameWithNamespace(field) + "').New()\n";
+      code += std::string(Indent) + Indent + "obj:Init(" + SelfDataBytes + ", x)\n";
+      code += std::string(Indent) + Indent + "return obj\n";
+      code += std::string(Indent) + End;
+      code += EndFunc;
+    }
+
+    // Get the value of a vector's non-struct member. Uses a named return
+    // argument to conveniently set the zero value for the result.
+    void GetMemberOfVectorOfNonStruct(const StructDef &struct_def,
+      const FieldDef &field,
+      std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      auto vectortype = field.value.type.VectorType();
+
+      GenReceiver(struct_def, code_ptr);
+      code += MakeCamel(NormalizedName(field));
+      code += "(j)\n";
+      code += OffsetPrefix(field);
+      code += std::string(Indent) + Indent + "local a = " + SelfData + ":Vector(o)\n";
+      code += std::string(Indent) + Indent;
+      code += "return " + GenGetter(field.value.type);
+      code += "a + ((j-1) * ";
+      code += NumToString(InlineSize(vectortype)) + "))\n";
+      code += std::string(Indent) + End;
+      if (vectortype.base_type == BASE_TYPE_STRING) {
+        code += std::string(Indent) + "return ''\n";
+      }
+      else {
+        code += std::string(Indent) + "return 0\n";
+      }
+      code += EndFunc;
+    }
+
+    // Begin the creator function signature.
+    void BeginBuilderArgs(const StructDef &struct_def,
+      std::string *code_ptr) {
+      std::string &code = *code_ptr;
+
+      code += "function " + NormalizedName(struct_def) + ".Create" + NormalizedName(struct_def);
+      code += "(builder";
+    }
+
+    // Recursively generate arguments for a constructor, to deal with nested
+    // structs.
+    void StructBuilderArgs(const StructDef &struct_def,
+      const char *nameprefix, std::string *code_ptr) {
+      for (auto it = struct_def.fields.vec.begin();
+        it != struct_def.fields.vec.end(); ++it) {
+        auto &field = **it;
+        if (IsStruct(field.value.type)) {
+          // Generate arguments for a struct inside a struct. To ensure names
+          // don't clash, and to make it obvious these arguments are constructing
+          // a nested struct, prefix the name with the field name.
+          StructBuilderArgs(*field.value.type.struct_def,
+            (nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr);
+        }
+        else {
+          std::string &code = *code_ptr;
+          code += std::string(", ") + nameprefix;
+          code += MakeCamel(NormalizedName(field), false);
+        }
+      }
+    }
+
+    // End the creator function signature.
+    void EndBuilderArgs(std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      code += ")\n";
+    }
+
+    // Recursively generate struct construction statements and instert manual
+    // padding.
+    void StructBuilderBody(const StructDef &struct_def,
+      const char *nameprefix, std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      code += std::string(Indent) + "builder:Prep(" + NumToString(struct_def.minalign) + ", ";
+      code += NumToString(struct_def.bytesize) + ")\n";
+      for (auto it = struct_def.fields.vec.rbegin();
+        it != struct_def.fields.vec.rend(); ++it) {
+        auto &field = **it;
+        if (field.padding)
+          code += std::string(Indent) + "builder:Pad(" + NumToString(field.padding) + ")\n";
+        if (IsStruct(field.value.type)) {
+          StructBuilderBody(*field.value.type.struct_def,
+            (nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr);
+        }
+        else {
+          code += std::string(Indent) + "builder:Prepend" + GenMethod(field) + "(";
+          code += nameprefix + MakeCamel(NormalizedName(field), false) + ")\n";
+        }
+      }
+    }
+
+    void EndBuilderBody(std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      code += std::string(Indent) + "return builder:Offset()\n";
+      code += EndFunc;
+    }
+
+    // Get the value of a table's starting offset.
+    void GetStartOfTable(const StructDef &struct_def,
+      std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      code += "function " + NormalizedName(struct_def) + ".Start";
+      code += "(builder) ";
+      code += "builder:StartObject(";
+      code += NumToString(struct_def.fields.vec.size());
+      code += ") end\n";
+    }
+
+    // Set the value of a table's field.
+    void BuildFieldOfTable(const StructDef &struct_def,
+      const FieldDef &field, const size_t offset,
+      std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      code += "function " + NormalizedName(struct_def) + ".Add" + MakeCamel(NormalizedName(field));
+      code += "(builder, ";
+      code += MakeCamel(NormalizedName(field), false);
+      code += ") ";
+      code += "builder:Prepend";
+      code += GenMethod(field) + "Slot(";
+      code += NumToString(offset) + ", ";
+      // todo: i don't need to cast in Lua, but am I missing something?
+    //    if (!IsScalar(field.value.type.base_type) && (!struct_def.fixed)) {
+    //      code += "flatbuffers.N.UOffsetTFlags.py_type";
+    //      code += "(";
+    //      code += MakeCamel(NormalizedName(field), false) + ")";
+    //    } else {
+      code += MakeCamel(NormalizedName(field), false);
+      //    }
+      code += ", " + field.value.constant;
+      code += ") end\n";
+    }
+
+    // Set the value of one of the members of a table's vector.
+    void BuildVectorOfTable(const StructDef &struct_def,
+      const FieldDef &field, std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      code += "function " + NormalizedName(struct_def) + ".Start";
+      code += MakeCamel(NormalizedName(field));
+      code += "Vector(builder, numElems) return builder:StartVector(";
+      auto vector_type = field.value.type.VectorType();
+      auto alignment = InlineAlignment(vector_type);
+      auto elem_size = InlineSize(vector_type);
+      code += NumToString(elem_size);
+      code += ", numElems, " + NumToString(alignment);
+      code += ") end\n";
+    }
+
+    // Get the offset of the end of a table.
+    void GetEndOffsetOnTable(const StructDef &struct_def,
+      std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      code += "function " + NormalizedName(struct_def) + ".End";
+      code += "(builder) ";
+      code += "return builder:EndObject() end\n";
+    }
+
+    // Generate the receiver for function signatures.
+    void GenReceiver(const StructDef &struct_def, std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      code += "function " + NormalizedMetaName(struct_def) + ":";
+    }
+
+    // Generate a struct field, conditioned on its child type(s).
+    void GenStructAccessor(const StructDef &struct_def,
+      const FieldDef &field, std::string *code_ptr) {
+      GenComment(field.doc_comment, code_ptr, &def_comment);
+      if (IsScalar(field.value.type.base_type)) {
+        if (struct_def.fixed) {
+          GetScalarFieldOfStruct(struct_def, field, code_ptr);
+        }
+        else {
+          GetScalarFieldOfTable(struct_def, field, code_ptr);
+        }
+      }
+      else {
+        switch (field.value.type.base_type) {
+        case BASE_TYPE_STRUCT:
+          if (struct_def.fixed) {
+            GetStructFieldOfStruct(struct_def, field, code_ptr);
+          }
+          else {
+            GetStructFieldOfTable(struct_def, field, code_ptr);
+          }
+          break;
+        case BASE_TYPE_STRING: GetStringField(struct_def, field, code_ptr); break;
+        case BASE_TYPE_VECTOR: {
+          auto vectortype = field.value.type.VectorType();
+          if (vectortype.base_type == BASE_TYPE_STRUCT) {
+            GetMemberOfVectorOfStruct(struct_def, field, code_ptr);
+          }
+          else {
+            GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr);
+          }
+          break;
+        }
+        case BASE_TYPE_UNION: GetUnionField(struct_def, field, code_ptr); break;
+        default: FLATBUFFERS_ASSERT(0);
+        }
+      }
+      if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+        GetVectorLen(struct_def, field, code_ptr);
+      }
+    }
+
+    // Generate table constructors, conditioned on its members' types.
+    void GenTableBuilders(const StructDef &struct_def,
+      std::string *code_ptr) {
+      GetStartOfTable(struct_def, code_ptr);
+
+      for (auto it = struct_def.fields.vec.begin();
+        it != struct_def.fields.vec.end(); ++it) {
+        auto &field = **it;
+        if (field.deprecated) continue;
+
+        auto offset = it - struct_def.fields.vec.begin();
+        BuildFieldOfTable(struct_def, field, offset, code_ptr);
+        if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+          BuildVectorOfTable(struct_def, field, code_ptr);
+        }
+      }
+
+      GetEndOffsetOnTable(struct_def, code_ptr);
+    }
+
+    // Generate struct or table methods.
+    void GenStruct(const StructDef &struct_def, std::string *code_ptr) {
+      if (struct_def.generated) return;
+
+      GenComment(struct_def.doc_comment, code_ptr, &def_comment);
+      BeginClass(struct_def, code_ptr);
+
+      GenerateNewObjectPrototype(struct_def, code_ptr);
+
+      if (!struct_def.fixed) {
+        // Generate a special accessor for the table that has been declared as
+        // the root type.
+        NewRootTypeFromBuffer(struct_def, code_ptr);
+      }
+
+      // Generate the Init method that sets the field in a pre-existing
+      // accessor object. This is to allow object reuse.
+      InitializeExisting(struct_def, code_ptr);
+      for (auto it = struct_def.fields.vec.begin();
+        it != struct_def.fields.vec.end(); ++it) {
+        auto &field = **it;
+        if (field.deprecated) continue;
+
+        GenStructAccessor(struct_def, field, code_ptr);
+      }
+
+      if (struct_def.fixed) {
+        // create a struct constructor function
+        GenStructBuilder(struct_def, code_ptr);
+      }
+      else {
+        // Create a set of functions that allow table construction.
+        GenTableBuilders(struct_def, code_ptr);
+      }
+    }
+
+    // Generate enum declarations.
+    void GenEnum(const EnumDef &enum_def, std::string *code_ptr) {
+      if (enum_def.generated) return;
+
+      GenComment(enum_def.doc_comment, code_ptr, &def_comment);
+      BeginEnum(NormalizedName(enum_def), code_ptr);
+      for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
+           ++it) {
+        auto &ev = **it;
+        GenComment(ev.doc_comment, code_ptr, &def_comment, Indent);
+        EnumMember(enum_def, ev, code_ptr);
+      }
+      EndEnum(code_ptr);
+    }
+
+    // Returns the function name that is able to read a value of the given type.
+    std::string GenGetter(const Type &type) {
+      switch (type.base_type) {
+      case BASE_TYPE_STRING: return std::string(SelfData) + ":String(";
+      case BASE_TYPE_UNION: return  std::string(SelfData) + ":Union(";
+      case BASE_TYPE_VECTOR: return GenGetter(type.VectorType());
+      default:
+        return std::string(SelfData) + ":Get(flatbuffers.N." +
+          MakeCamel(GenTypeGet(type)) + ", ";
+      }
+    }
+
+    // Returns the method name for use with add/put calls.
+    std::string GenMethod(const FieldDef &field) {
+      return IsScalar(field.value.type.base_type)
+        ? MakeCamel(GenTypeBasic(field.value.type))
+        : (IsStruct(field.value.type) ? "Struct" : "UOffsetTRelative");
+    }
+
+    std::string GenTypeBasic(const Type &type) {
+      static const char *ctypename[] = {
+        // clang-format off
+          #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+            CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
+            #PTYPE,
+            FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+          #undef FLATBUFFERS_TD
+            // clang-format on
+      };
+      return ctypename[type.base_type];
+    }
+
+    std::string GenTypePointer(const Type &type) {
+      switch (type.base_type) {
+      case BASE_TYPE_STRING: return "string";
+      case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType());
+      case BASE_TYPE_STRUCT: return type.struct_def->name;
+      case BASE_TYPE_UNION:
+        // fall through
+      default: return "*flatbuffers.Table";
+      }
+    }
+
+    std::string GenTypeGet(const Type &type) {
+      return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type);
+    }
+
+    std::string GetNamespace(const Type &type) {
+      return type.struct_def->defined_namespace->GetFullyQualifiedName(type.struct_def->name);
+    }
+
+    std::string TypeName(const FieldDef &field) {
+      return GenTypeGet(field.value.type);
+    }
+
+    std::string TypeNameWithNamespace(const FieldDef &field) {
+      return GetNamespace(field.value.type);
+    }
+
+    // Create a struct with a builder and the struct's arguments.
+    void GenStructBuilder(const StructDef &struct_def,
+      std::string *code_ptr) {
+      BeginBuilderArgs(struct_def, code_ptr);
+      StructBuilderArgs(struct_def, "", code_ptr);
+      EndBuilderArgs(code_ptr);
+
+      StructBuilderBody(struct_def, "", code_ptr);
+      EndBuilderBody(code_ptr);
+    }
+
+    bool generate() {
+      if (!generateEnums()) return false;
+      if (!generateStructs()) return false;
+      return true;
+    }
+
+  private:
+    bool generateEnums() {
+      for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
+        ++it) {
+        auto &enum_def = **it;
+        std::string enumcode;
+        GenEnum(enum_def, &enumcode);
+        if (!SaveType(enum_def, enumcode, false)) return false;
+      }
+      return true;
+    }
+
+    bool generateStructs() {
+      for (auto it = parser_.structs_.vec.begin();
+        it != parser_.structs_.vec.end(); ++it) {
+        auto &struct_def = **it;
+        std::string declcode;
+        GenStruct(struct_def, &declcode);
+        if (!SaveType(struct_def, declcode, true)) return false;
+      }
+      return true;
+    }
+
+    // Begin by declaring namespace and imports.
+    void BeginFile(const std::string &name_space_name, const bool needs_imports,
+      std::string *code_ptr) {
+      std::string &code = *code_ptr;
+      code += std::string(Comment) + FlatBuffersGeneratedWarning() + "\n\n";
+      code += std::string(Comment) + "namespace: " + name_space_name + "\n\n";
+      if (needs_imports) {
+        code += "local flatbuffers = require('flatbuffers')\n\n";
+      }
+    }
+
+    // Save out the generated code for a Lua Table type.
+    bool SaveType(const Definition &def, const std::string &classcode,
+      bool needs_imports) {
+      if (!classcode.length()) return true;
+
+      std::string namespace_dir = path_;
+      auto &namespaces = def.defined_namespace->components;
+      for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
+        if (it != namespaces.begin()) namespace_dir += kPathSeparator;
+        namespace_dir += *it;
+        //std::string init_py_filename = namespace_dir + "/__init__.py";
+        //SaveFile(init_py_filename.c_str(), "", false);
+      }
+
+      std::string code = "";
+      BeginFile(LastNamespacePart(*def.defined_namespace), needs_imports, &code);
+      code += classcode;
+      code += "\n";
+      code += "return " + NormalizedName(def) + " " + Comment + "return the module";
+      std::string filename =
+        NamespaceDir(*def.defined_namespace) + NormalizedName(def) + ".lua";
+      return SaveFile(filename.c_str(), code, false);
+    }
+  private:
+    std::unordered_set<std::string> keywords_;
+  };
+
+}  // namespace lua
+
+bool GenerateLua(const Parser &parser, const std::string &path,
+  const std::string &file_name) {
+  lua::LuaGenerator generator(parser, path, file_name);
+  return generator.generate();
+}
+
+}  // namespace flatbuffers
diff --git a/src/idl_gen_php.cpp b/src/idl_gen_php.cpp
new file mode 100644
index 0000000..9d81415
--- /dev/null
+++ b/src/idl_gen_php.cpp
@@ -0,0 +1,940 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// independent from idl_parser, since this code is not needed for most clients
+
+#include <string>
+
+#include "flatbuffers/code_generators.h"
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+namespace flatbuffers {
+namespace php {
+// Hardcode spaces per indentation.
+const std::string Indent = "    ";
+class PhpGenerator : public BaseGenerator {
+ public:
+  PhpGenerator(const Parser &parser, const std::string &path,
+               const std::string &file_name)
+      : BaseGenerator(parser, path, file_name, "\\", "\\") {}
+  bool generate() {
+    if (!GenerateEnums()) return false;
+    if (!GenerateStructs()) return false;
+    return true;
+  }
+
+ private:
+  bool GenerateEnums() {
+    for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
+         ++it) {
+      auto &enum_def = **it;
+      std::string enumcode;
+      GenEnum(enum_def, &enumcode);
+      if (!SaveType(enum_def, enumcode, false)) return false;
+    }
+    return true;
+  }
+
+  bool GenerateStructs() {
+    for (auto it = parser_.structs_.vec.begin();
+         it != parser_.structs_.vec.end(); ++it) {
+      auto &struct_def = **it;
+      std::string declcode;
+      GenStruct(struct_def, &declcode);
+      if (!SaveType(struct_def, declcode, true)) return false;
+    }
+    return true;
+  }
+
+  // Begin by declaring namespace and imports.
+  void BeginFile(const std::string &name_space_name, const bool needs_imports,
+                 std::string *code_ptr) {
+    auto &code = *code_ptr;
+    code += "<?php\n";
+    code = code + "// " + FlatBuffersGeneratedWarning() + "\n\n";
+
+    if (!name_space_name.empty()) {
+      code += "namespace " + name_space_name + ";\n\n";
+    }
+
+    if (needs_imports) {
+      code += "use \\Google\\FlatBuffers\\Struct;\n";
+      code += "use \\Google\\FlatBuffers\\Table;\n";
+      code += "use \\Google\\FlatBuffers\\ByteBuffer;\n";
+      code += "use \\Google\\FlatBuffers\\FlatBufferBuilder;\n";
+      code += "\n";
+    }
+  }
+
+  // Save out the generated code for a Php Table type.
+  bool SaveType(const Definition &def, const std::string &classcode,
+                bool needs_imports) {
+    if (!classcode.length()) return true;
+
+    std::string code = "";
+    BeginFile(FullNamespace("\\", *def.defined_namespace), needs_imports,
+              &code);
+    code += classcode;
+
+    std::string filename =
+        NamespaceDir(*def.defined_namespace) + def.name + ".php";
+    return SaveFile(filename.c_str(), code, false);
+  }
+
+  // Begin a class declaration.
+  static void BeginClass(const StructDef &struct_def, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    if (struct_def.fixed) {
+      code += "class " + struct_def.name + " extends Struct\n";
+    } else {
+      code += "class " + struct_def.name + " extends Table\n";
+    }
+    code += "{\n";
+  }
+
+  static void EndClass(std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "}\n";
+  }
+
+  // Begin enum code with a class declaration.
+  static void BeginEnum(const std::string &class_name, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "class " + class_name + "\n{\n";
+  }
+
+  // A single enum member.
+  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 += enum_def.ToString(ev) + ";\n";
+  }
+
+  // End enum code.
+  static void EndEnum(std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "}\n";
+  }
+
+  // Initialize a new struct or table from existing data.
+  static void NewRootTypeFromBuffer(const StructDef &struct_def,
+                                    std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    code += Indent + "/**\n";
+    code += Indent + " * @param ByteBuffer $bb\n";
+    code += Indent + " * @return " + struct_def.name + "\n";
+    code += Indent + " */\n";
+    code += Indent + "public static function getRootAs";
+    code += struct_def.name;
+    code += "(ByteBuffer $bb)\n";
+    code += Indent + "{\n";
+
+    code += Indent + Indent + "$obj = new " + struct_def.name + "();\n";
+    code += Indent + Indent;
+    code += "return ($obj->init($bb->getInt($bb->getPosition())";
+    code += " + $bb->getPosition(), $bb));\n";
+    code += Indent + "}\n\n";
+  }
+
+  // Initialize an existing object with other data, to avoid an allocation.
+  static void InitializeExisting(const StructDef &struct_def,
+                                 std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    code += Indent + "/**\n";
+    code += Indent + " * @param int $_i offset\n";
+    code += Indent + " * @param ByteBuffer $_bb\n";
+    code += Indent + " * @return " + struct_def.name + "\n";
+    code += Indent + " **/\n";
+    code += Indent + "public function init($_i, ByteBuffer $_bb)\n";
+    code += Indent + "{\n";
+    code += Indent + Indent + "$this->bb_pos = $_i;\n";
+    code += Indent + Indent + "$this->bb = $_bb;\n";
+    code += Indent + Indent + "return $this;\n";
+    code += Indent + "}\n\n";
+  }
+
+  // Get the length of a vector.
+  static void GetVectorLen(const FieldDef &field, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    code += Indent + "/**\n";
+    code += Indent + " * @return int\n";
+    code += Indent + " */\n";
+    code += Indent + "public function get";
+    code += MakeCamel(field.name) + "Length()\n";
+    code += Indent + "{\n";
+    code += Indent + Indent + "$o = $this->__offset(";
+    code += NumToString(field.value.offset) + ");\n";
+    code += Indent + Indent;
+    code += "return $o != 0 ? $this->__vector_len($o) : 0;\n";
+    code += Indent + "}\n\n";
+  }
+
+  // Get a [ubyte] vector as a byte array.
+  static void GetUByte(const FieldDef &field, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    code += Indent + "/**\n";
+    code += Indent + " * @return string\n";
+    code += Indent + " */\n";
+    code += Indent + "public function get";
+    code += MakeCamel(field.name) + "Bytes()\n";
+    code += Indent + "{\n";
+    code += Indent + Indent + "return $this->__vector_as_bytes(";
+    code += NumToString(field.value.offset) + ");\n";
+    code += Indent + "}\n\n";
+  }
+
+  // Get the value of a struct's scalar.
+  static void GetScalarFieldOfStruct(const FieldDef &field,
+                                     std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    std::string getter = GenGetter(field.value.type);
+
+    code += Indent + "/**\n";
+    code += Indent + " * @return ";
+    code += GenTypeGet(field.value.type) + "\n";
+    code += Indent + " */\n";
+    code += Indent + "public function " + getter;
+    code += MakeCamel(field.name) + "()\n";
+    code += Indent + "{\n";
+    code += Indent + Indent + "return ";
+
+    code += "$this->bb->get";
+    code += MakeCamel(GenTypeGet(field.value.type));
+    code += "($this->bb_pos + ";
+    code += NumToString(field.value.offset) + ")";
+    code += ";\n";
+
+    code += Indent + "}\n\n";
+  }
+
+  // Get the value of a table's scalar.
+  void GetScalarFieldOfTable(const FieldDef &field, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    code += Indent + "/**\n";
+    code += Indent + " * @return " + GenTypeGet(field.value.type) + "\n";
+    code += Indent + " */\n";
+    code += Indent + "public function get";
+    code += MakeCamel(field.name);
+    code += "()\n";
+    code += Indent + "{\n";
+    code += Indent + Indent + "$o = $this->__offset(" +
+            NumToString(field.value.offset) + ");\n" + Indent + Indent +
+            "return $o != 0 ? ";
+    code += "$this->bb->get";
+    code += MakeCamel(GenTypeGet(field.value.type)) + "($o + $this->bb_pos)";
+    code += " : " + GenDefaultValue(field.value) + ";\n";
+    code += Indent + "}\n\n";
+  }
+
+  // Get a struct by initializing an existing struct.
+  // Specific to Struct.
+  void GetStructFieldOfStruct(const FieldDef &field, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    code += Indent + "/**\n";
+    code += Indent + " * @return " + GenTypeGet(field.value.type) + "\n";
+    code += Indent + " */\n";
+    code += Indent + "public function get";
+    code += MakeCamel(field.name) + "()\n";
+    code += Indent + "{\n";
+    code += Indent + Indent + "$obj = new ";
+    code += GenTypeGet(field.value.type) + "();\n";
+    code += Indent + Indent + "$obj->init($this->bb_pos + ";
+    code += NumToString(field.value.offset) + ", $this->bb);";
+    code += "\n" + Indent + Indent + "return $obj;\n";
+    code += Indent + "}\n\n";
+  }
+
+  // Get a struct by initializing an existing struct.
+  // Specific to Table.
+  void GetStructFieldOfTable(const FieldDef &field, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    code += Indent + "public function get";
+    code += MakeCamel(field.name);
+    code += "()\n";
+    code += Indent + "{\n";
+    code += Indent + Indent + "$obj = new ";
+    code += MakeCamel(GenTypeGet(field.value.type)) + "();\n";
+    code += Indent + Indent + "$o = $this->__offset(" +
+            NumToString(field.value.offset) + ");\n";
+    code += Indent + Indent;
+    code += "return $o != 0 ? $obj->init(";
+    if (field.value.type.struct_def->fixed) {
+      code += "$o + $this->bb_pos, $this->bb) : ";
+    } else {
+      code += "$this->__indirect($o + $this->bb_pos), $this->bb) : ";
+    }
+    code += GenDefaultValue(field.value) + ";\n";
+    code += Indent + "}\n\n";
+  }
+
+  // Get the value of a string.
+  void GetStringField(const FieldDef &field, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += Indent + "public function get";
+    code += MakeCamel(field.name);
+    code += "()\n";
+    code += Indent + "{\n";
+    code += Indent + Indent + "$o = $this->__offset(" +
+            NumToString(field.value.offset) + ");\n";
+    code += Indent + Indent;
+    code += "return $o != 0 ? $this->__string($o + $this->bb_pos) : ";
+    code += GenDefaultValue(field.value) + ";\n";
+    code += Indent + "}\n\n";
+  }
+
+  // Get the value of a union from an object.
+  void GetUnionField(const FieldDef &field, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    code += Indent + "/**\n";
+    code += Indent + " * @return" + GenTypeBasic(field.value.type) + "\n";
+    code += Indent + " */\n";
+    code += Indent + "public function get";
+    code += MakeCamel(field.name) + "($obj)\n";
+    code += Indent + "{\n";
+    code += Indent + Indent + "$o = $this->__offset(" +
+            NumToString(field.value.offset) + ");\n";
+    code += Indent + Indent;
+    code += "return $o != 0 ? $this->__union($obj, $o) : null;\n";
+    code += Indent + "}\n\n";
+  }
+
+  // Get the value of a vector's struct member.
+  void GetMemberOfVectorOfStruct(const StructDef &struct_def,
+                                 const FieldDef &field, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    auto vectortype = field.value.type.VectorType();
+
+    code += Indent + "/**\n";
+    code += Indent + " * @return" + GenTypeBasic(field.value.type) + "\n";
+    code += Indent + " */\n";
+    code += Indent + "public function get";
+    code += MakeCamel(field.name);
+    code += "($j)\n";
+    code += Indent + "{\n";
+    code += Indent + Indent + "$o = $this->__offset(" +
+            NumToString(field.value.offset) + ");\n";
+    code += Indent + Indent + "$obj = new ";
+    code += MakeCamel(GenTypeGet(field.value.type)) + "();\n";
+
+    switch (field.value.type.base_type) {
+      case BASE_TYPE_STRUCT:
+        if (struct_def.fixed) {
+          code += Indent + Indent;
+          code += "return $o != 0 ? $obj->init($this->bb_pos +" +
+                  NumToString(field.value.offset) + ", $this->bb) : null;\n";
+        } else {
+          code += Indent + Indent + "return $o != 0 ? $obj->init(";
+          code += field.value.type.struct_def->fixed
+                      ? "$o + $this->bb_pos"
+                      : "$this->__indirect($o + $this->bb_pos)";
+          code += ", $this->bb) : null;\n";
+        }
+        break;
+      case BASE_TYPE_STRING:
+        code += "// base_type_string\n";
+        // TODO(chobie): do we need this?
+        break;
+      case BASE_TYPE_VECTOR:
+        if (vectortype.base_type == BASE_TYPE_STRUCT) {
+          code += Indent + Indent + "return $o != 0 ? $obj->init(";
+          if (vectortype.struct_def->fixed) {
+            code += "$this->__vector($o) + $j *";
+            code += NumToString(InlineSize(vectortype));
+          } else {
+            code += "$this->__indirect($this->__vector($o) + $j * ";
+            code += NumToString(InlineSize(vectortype)) + ")";
+          }
+          code += ", $this->bb) : null;\n";
+        }
+        break;
+      case BASE_TYPE_UNION:
+        code += Indent + Indent + "return $o != 0 ? $this->";
+        code += GenGetter(field.value.type) + "($obj, $o); null;\n";
+        break;
+      default: break;
+    }
+
+    code += Indent + "}\n\n";
+  }
+
+  // Get the value of a vector's non-struct member. Uses a named return
+  // argument to conveniently set the zero value for the result.
+  void GetMemberOfVectorOfNonStruct(const FieldDef &field,
+                                    std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    auto vectortype = field.value.type.VectorType();
+
+    code += Indent + "/**\n";
+    code += Indent + " * @param int offset\n";
+    code += Indent + " * @return " + GenTypeGet(field.value.type) + "\n";
+    code += Indent + " */\n";
+    code += Indent + "public function get";
+    code += MakeCamel(field.name);
+    code += "($j)\n";
+    code += Indent + "{\n";
+    code += Indent + Indent + "$o = $this->__offset(" +
+            NumToString(field.value.offset) + ");\n";
+
+    if (field.value.type.VectorType().base_type == BASE_TYPE_STRING) {
+      code += Indent + Indent;
+      code += "return $o != 0 ? $this->__string($this->__vector($o) + $j * ";
+      code += NumToString(InlineSize(vectortype)) + ") : ";
+      code += GenDefaultValue(field.value) + ";\n";
+    } else {
+      code += Indent + Indent + "return $o != 0 ? $this->bb->get";
+      code += MakeCamel(GenTypeGet(field.value.type));
+      code += "($this->__vector($o) + $j * ";
+      code += NumToString(InlineSize(vectortype)) + ") : ";
+      code += GenDefaultValue(field.value) + ";\n";
+    }
+    code += Indent + "}\n\n";
+  }
+
+  // Get the value of a vector's union member. Uses a named return
+  // argument to conveniently set the zero value for the result.
+  void GetMemberOfVectorOfUnion(const FieldDef &field, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    auto vectortype = field.value.type.VectorType();
+
+    code += Indent + "/**\n";
+    code += Indent + " * @param int offset\n";
+    code += Indent + " * @return " + GenTypeGet(field.value.type) + "\n";
+    code += Indent + " */\n";
+    code += Indent + "public function get";
+    code += MakeCamel(field.name);
+    code += "($j, $obj)\n";
+    code += Indent + "{\n";
+    code += Indent + Indent + "$o = $this->__offset(" +
+            NumToString(field.value.offset) + ");\n";
+    code += Indent + Indent + "return $o != 0 ? ";
+    code += "$this->__union($obj, $this->__vector($o) + $j * ";
+    code += NumToString(InlineSize(vectortype)) + " - $this->bb_pos) : null;\n";
+    code += Indent + "}\n\n";
+  }
+
+  // Recursively generate arguments for a constructor, to deal with nested
+  // structs.
+  static void StructBuilderArgs(const StructDef &struct_def,
+                                const char *nameprefix, std::string *code_ptr) {
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (IsStruct(field.value.type)) {
+        // Generate arguments for a struct inside a struct. To ensure names
+        // don't clash, and to make it obvious
+        // these arguments are constructing
+        // a nested struct, prefix the name with the field name.
+        StructBuilderArgs(*field.value.type.struct_def,
+                          (nameprefix + (field.name + "_")).c_str(), code_ptr);
+      } else {
+        std::string &code = *code_ptr;
+        code += std::string(", $") + nameprefix;
+        code += MakeCamel(field.name, false);
+      }
+    }
+  }
+
+  // Recursively generate struct construction statements and instert manual
+  // padding.
+  static void StructBuilderBody(const StructDef &struct_def,
+                                const char *nameprefix, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += Indent + Indent + "$builder->prep(";
+    code += NumToString(struct_def.minalign) + ", ";
+    code += NumToString(struct_def.bytesize) + ");\n";
+    for (auto it = struct_def.fields.vec.rbegin();
+         it != struct_def.fields.vec.rend(); ++it) {
+      auto &field = **it;
+      if (field.padding) {
+        code += Indent + Indent + "$builder->pad(";
+        code += NumToString(field.padding) + ");\n";
+      }
+      if (IsStruct(field.value.type)) {
+        StructBuilderBody(*field.value.type.struct_def,
+                          (nameprefix + (field.name + "_")).c_str(), code_ptr);
+      } else {
+        code += Indent + Indent + "$builder->put" + GenMethod(field) + "($";
+        code += nameprefix + MakeCamel(field.name, false) + ");\n";
+      }
+    }
+  }
+
+  // Get the value of a table's starting offset.
+  static void GetStartOfTable(const StructDef &struct_def,
+                              std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    code += Indent + "/**\n";
+    code += Indent + " * @param FlatBufferBuilder $builder\n";
+    code += Indent + " * @return void\n";
+    code += Indent + " */\n";
+    code += Indent + "public static function start" + struct_def.name;
+    code += "(FlatBufferBuilder $builder)\n";
+    code += Indent + "{\n";
+    code += Indent + Indent + "$builder->StartObject(";
+    code += NumToString(struct_def.fields.vec.size());
+    code += ");\n";
+    code += Indent + "}\n\n";
+
+    code += Indent + "/**\n";
+    code += Indent + " * @param FlatBufferBuilder $builder\n";
+    code += Indent + " * @return " + struct_def.name + "\n";
+    code += Indent + " */\n";
+    code += Indent + "public static function create" + struct_def.name;
+    code += "(FlatBufferBuilder $builder, ";
+
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+
+      if (field.deprecated) continue;
+      code += "$" + field.name;
+      if (!(it == (--struct_def.fields.vec.end()))) { code += ", "; }
+    }
+    code += ")\n";
+    code += Indent + "{\n";
+    code += Indent + Indent + "$builder->startObject(";
+    code += NumToString(struct_def.fields.vec.size());
+    code += ");\n";
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+
+      code += Indent + Indent + "self::add";
+      code += MakeCamel(field.name) + "($builder, $" + field.name + ");\n";
+    }
+
+    code += Indent + Indent + "$o = $builder->endObject();\n";
+
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (!field.deprecated && field.required) {
+        code += Indent + Indent + "$builder->required($o, ";
+        code += NumToString(field.value.offset);
+        code += ");  // " + field.name + "\n";
+      }
+    }
+    code += Indent + Indent + "return $o;\n";
+    code += Indent + "}\n\n";
+  }
+
+  // Set the value of a table's field.
+  static void BuildFieldOfTable(const FieldDef &field, const size_t offset,
+                                std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    code += Indent + "/**\n";
+    code += Indent + " * @param FlatBufferBuilder $builder\n";
+    code += Indent + " * @param " + GenTypeBasic(field.value.type) + "\n";
+    code += Indent + " * @return void\n";
+    code += Indent + " */\n";
+    code += Indent + "public static function ";
+    code += "add" + MakeCamel(field.name);
+    code += "(FlatBufferBuilder $builder, ";
+    code += "$" + MakeCamel(field.name, false);
+    code += ")\n";
+    code += Indent + "{\n";
+    code += Indent + Indent + "$builder->add";
+    code += GenMethod(field) + "X(";
+    code += NumToString(offset) + ", ";
+
+    code += "$" + MakeCamel(field.name, false);
+    code += ", ";
+
+    if (field.value.type.base_type == BASE_TYPE_BOOL) {
+      code += "false";
+    } else {
+      code += field.value.constant;
+    }
+    code += ");\n";
+    code += Indent + "}\n\n";
+  }
+
+  // Set the value of one of the members of a table's vector.
+  static void BuildVectorOfTable(const FieldDef &field, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    auto vector_type = field.value.type.VectorType();
+    auto alignment = InlineAlignment(vector_type);
+    auto elem_size = InlineSize(vector_type);
+    code += Indent + "/**\n";
+    code += Indent + " * @param FlatBufferBuilder $builder\n";
+    code += Indent + " * @param array offset array\n";
+    code += Indent + " * @return int vector offset\n";
+    code += Indent + " */\n";
+    code += Indent + "public static function create";
+    code += MakeCamel(field.name);
+    code += "Vector(FlatBufferBuilder $builder, array $data)\n";
+    code += Indent + "{\n";
+    code += Indent + Indent + "$builder->startVector(";
+    code += NumToString(elem_size);
+    code += ", count($data), " + NumToString(alignment);
+    code += ");\n";
+    code += Indent + Indent;
+    code += "for ($i = count($data) - 1; $i >= 0; $i--) {\n";
+    if (IsScalar(field.value.type.VectorType().base_type)) {
+      code += Indent + Indent + Indent;
+      code += "$builder->put";
+      code += MakeCamel(GenTypeBasic(field.value.type.VectorType()));
+      code += "($data[$i]);\n";
+    } else {
+      code += Indent + Indent + Indent;
+      code += "$builder->putOffset($data[$i]);\n";
+    }
+    code += Indent + Indent + "}\n";
+    code += Indent + Indent + "return $builder->endVector();\n";
+    code += Indent + "}\n\n";
+
+    code += Indent + "/**\n";
+    code += Indent + " * @param FlatBufferBuilder $builder\n";
+    code += Indent + " * @param int $numElems\n";
+    code += Indent + " * @return void\n";
+    code += Indent + " */\n";
+    code += Indent + "public static function start";
+    code += MakeCamel(field.name);
+    code += "Vector(FlatBufferBuilder $builder, $numElems)\n";
+    code += Indent + "{\n";
+    code += Indent + Indent + "$builder->startVector(";
+    code += NumToString(elem_size);
+    code += ", $numElems, " + NumToString(alignment);
+    code += ");\n";
+    code += Indent + "}\n\n";
+  }
+
+  // Get the offset of the end of a table.
+  void GetEndOffsetOnTable(const StructDef &struct_def, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    code += Indent + "/**\n";
+    code += Indent + " * @param FlatBufferBuilder $builder\n";
+    code += Indent + " * @return int table offset\n";
+    code += Indent + " */\n";
+    code += Indent + "public static function end" + struct_def.name;
+    code += "(FlatBufferBuilder $builder)\n";
+    code += Indent + "{\n";
+    code += Indent + Indent + "$o = $builder->endObject();\n";
+
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (!field.deprecated && field.required) {
+        code += Indent + Indent + "$builder->required($o, ";
+        code += NumToString(field.value.offset);
+        code += ");  // " + field.name + "\n";
+      }
+    }
+    code += Indent + Indent + "return $o;\n";
+    code += Indent + "}\n";
+
+    if (parser_.root_struct_def_ == &struct_def) {
+      code += "\n";
+      code += Indent + "public static function finish";
+      code += struct_def.name;
+      code += "Buffer(FlatBufferBuilder $builder, $offset)\n";
+      code += Indent + "{\n";
+      code += Indent + Indent + "$builder->finish($offset";
+
+      if (parser_.file_identifier_.length())
+        code += ", \"" + parser_.file_identifier_ + "\"";
+      code += ");\n";
+      code += Indent + "}\n";
+    }
+  }
+
+  // Generate a struct field, conditioned on its child type(s).
+  void GenStructAccessor(const StructDef &struct_def, const FieldDef &field,
+                         std::string *code_ptr) {
+    GenComment(field.doc_comment, code_ptr, nullptr, Indent.c_str());
+
+    if (IsScalar(field.value.type.base_type)) {
+      if (struct_def.fixed) {
+        GetScalarFieldOfStruct(field, code_ptr);
+      } else {
+        GetScalarFieldOfTable(field, code_ptr);
+      }
+    } else {
+      switch (field.value.type.base_type) {
+        case BASE_TYPE_STRUCT:
+          if (struct_def.fixed) {
+            GetStructFieldOfStruct(field, code_ptr);
+          } else {
+            GetStructFieldOfTable(field, code_ptr);
+          }
+          break;
+        case BASE_TYPE_STRING: GetStringField(field, code_ptr); break;
+        case BASE_TYPE_VECTOR: {
+          auto vectortype = field.value.type.VectorType();
+          if (vectortype.base_type == BASE_TYPE_UNION) {
+            GetMemberOfVectorOfUnion(field, code_ptr);
+          } else if (vectortype.base_type == BASE_TYPE_STRUCT) {
+            GetMemberOfVectorOfStruct(struct_def, field, code_ptr);
+          } else {
+            GetMemberOfVectorOfNonStruct(field, code_ptr);
+          }
+          break;
+        }
+        case BASE_TYPE_UNION: GetUnionField(field, code_ptr); break;
+        default: FLATBUFFERS_ASSERT(0);
+      }
+    }
+    if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+      GetVectorLen(field, code_ptr);
+      if (field.value.type.element == BASE_TYPE_UCHAR) {
+        GetUByte(field, code_ptr);
+      }
+    }
+  }
+
+  // Generate table constructors, conditioned on its members' types.
+  void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) {
+    GetStartOfTable(struct_def, code_ptr);
+
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+
+      auto offset = it - struct_def.fields.vec.begin();
+      if (field.value.type.base_type == BASE_TYPE_UNION) {
+        std::string &code = *code_ptr;
+        code += Indent + "public static function add";
+        code += MakeCamel(field.name);
+        code += "(FlatBufferBuilder $builder, $offset)\n";
+        code += Indent + "{\n";
+        code += Indent + Indent + "$builder->addOffsetX(";
+        code += NumToString(offset) + ", $offset, 0);\n";
+        code += Indent + "}\n\n";
+      } else {
+        BuildFieldOfTable(field, offset, code_ptr);
+      }
+      if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+        BuildVectorOfTable(field, code_ptr);
+      }
+    }
+
+    GetEndOffsetOnTable(struct_def, code_ptr);
+  }
+
+  // Generate struct or table methods.
+  void GenStruct(const StructDef &struct_def, std::string *code_ptr) {
+    if (struct_def.generated) return;
+
+    GenComment(struct_def.doc_comment, code_ptr, nullptr);
+    BeginClass(struct_def, code_ptr);
+
+    if (!struct_def.fixed) {
+      // Generate a special accessor for the table that has been declared as
+      // the root type.
+      NewRootTypeFromBuffer(struct_def, code_ptr);
+    }
+
+    std::string &code = *code_ptr;
+    if (!struct_def.fixed) {
+      if (parser_.file_identifier_.length()) {
+        // Return the identifier
+        code += Indent + "public static function " + struct_def.name;
+        code += "Identifier()\n";
+        code += Indent + "{\n";
+        code += Indent + Indent + "return \"";
+        code += parser_.file_identifier_ + "\";\n";
+        code += Indent + "}\n\n";
+
+        // Check if a buffer has the identifier.
+        code += Indent + "public static function " + struct_def.name;
+        code += "BufferHasIdentifier(ByteBuffer $buf)\n";
+        code += Indent + "{\n";
+        code += Indent + Indent + "return self::";
+        code += "__has_identifier($buf, self::";
+        code += struct_def.name + "Identifier());\n";
+        code += Indent + "}\n\n";
+      }
+
+      if (parser_.file_extension_.length()) {
+        // Return the extension
+        code += Indent + "public static function " + struct_def.name;
+        code += "Extension()\n";
+        code += Indent + "{\n";
+        code += Indent + Indent + "return \"" + parser_.file_extension_;
+        code += "\";\n";
+        code += Indent + "}\n\n";
+      }
+    }
+
+    // Generate the Init method that sets the field in a pre-existing
+    // accessor object. This is to allow object reuse.
+    InitializeExisting(struct_def, code_ptr);
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+
+      GenStructAccessor(struct_def, field, code_ptr);
+    }
+
+    if (struct_def.fixed) {
+      // create a struct constructor function
+      GenStructBuilder(struct_def, code_ptr);
+    } else {
+      // Create a set of functions that allow table construction.
+      GenTableBuilders(struct_def, code_ptr);
+    }
+    EndClass(code_ptr);
+  }
+
+  // Generate enum declarations.
+  static void GenEnum(const EnumDef &enum_def, std::string *code_ptr) {
+    if (enum_def.generated) return;
+
+    GenComment(enum_def.doc_comment, code_ptr, nullptr);
+    BeginEnum(enum_def.name, code_ptr);
+    for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
+      auto &ev = **it;
+      GenComment(ev.doc_comment, code_ptr, nullptr, Indent.c_str());
+      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().begin(); it != enum_def.Vals().end(); ++it) {
+      auto &ev = **it;
+      code += Indent + Indent + enum_def.name + "::" + ev.name + "=>" + "\"" + ev.name + "\",\n";
+    }
+
+    code += Indent + ");\n\n";
+    code += Indent + "public static function Name($e)\n";
+    code += Indent + "{\n";
+    code += Indent + Indent + "if (!isset(self::$names[$e])) {\n";
+    code += Indent + Indent + Indent + "throw new \\Exception();\n";
+    code += Indent + Indent + "}\n";
+    code += Indent + Indent + "return self::$names[$e];\n";
+    code += Indent + "}\n";
+    EndEnum(code_ptr);
+  }
+
+  // Returns the function name that is able to read a value of the given type.
+  static std::string GenGetter(const Type &type) {
+    switch (type.base_type) {
+      case BASE_TYPE_STRING: return "__string";
+      case BASE_TYPE_STRUCT: return "__struct";
+      case BASE_TYPE_UNION: return "__union";
+      case BASE_TYPE_VECTOR: return GenGetter(type.VectorType());
+      default: return "Get";
+    }
+  }
+
+  // Returns the method name for use with add/put calls.
+  static std::string GenMethod(const FieldDef &field) {
+    return IsScalar(field.value.type.base_type)
+               ? MakeCamel(GenTypeBasic(field.value.type))
+               : (IsStruct(field.value.type) ? "Struct" : "Offset");
+  }
+
+  static std::string GenTypeBasic(const Type &type) {
+    static const char *ctypename[] = {
+    // clang-format off
+        #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+            CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
+            #NTYPE,
+                FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+        #undef FLATBUFFERS_TD
+      // clang-format on
+    };
+    return ctypename[type.base_type];
+  }
+
+  std::string GenDefaultValue(const Value &value) {
+    if (value.type.enum_def) {
+      if (auto val = value.type.enum_def->FindByValue(value.constant)) {
+        return WrapInNameSpace(*value.type.enum_def) + "::" + val->name;
+      }
+    }
+
+    switch (value.type.base_type) {
+      case BASE_TYPE_BOOL: return value.constant == "0" ? "false" : "true";
+
+      case BASE_TYPE_STRING: return "null";
+
+      case BASE_TYPE_LONG:
+      case BASE_TYPE_ULONG:
+        if (value.constant != "0") {
+          int64_t constant = StringToInt(value.constant.c_str());
+          return NumToString(constant);
+        }
+        return "0";
+
+      default: return value.constant;
+    }
+  }
+
+  static std::string GenTypePointer(const Type &type) {
+    switch (type.base_type) {
+      case BASE_TYPE_STRING: return "string";
+      case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType());
+      case BASE_TYPE_STRUCT: return type.struct_def->name;
+      case BASE_TYPE_UNION:
+        // fall through
+      default: return "Table";
+    }
+  }
+
+  static std::string GenTypeGet(const Type &type) {
+    return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type);
+  }
+
+  // Create a struct with a builder and the struct's arguments.
+  static void GenStructBuilder(const StructDef &struct_def,
+                               std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "\n";
+    code += Indent + "/**\n";
+    code += Indent + " * @return int offset\n";
+    code += Indent + " */\n";
+    code += Indent + "public static function create" + struct_def.name;
+    code += "(FlatBufferBuilder $builder";
+    StructBuilderArgs(struct_def, "", code_ptr);
+    code += ")\n";
+    code += Indent + "{\n";
+
+    StructBuilderBody(struct_def, "", code_ptr);
+
+    code += Indent + Indent + "return $builder->offset();\n";
+    code += Indent + "}\n";
+  }
+};
+}  // namespace php
+
+bool GeneratePhp(const Parser &parser, const std::string &path,
+                 const std::string &file_name) {
+  php::PhpGenerator generator(parser, path, file_name);
+  return generator.generate();
+}
+}  // namespace flatbuffers
diff --git a/src/idl_gen_python.cpp b/src/idl_gen_python.cpp
new file mode 100644
index 0000000..c8db359
--- /dev/null
+++ b/src/idl_gen_python.cpp
@@ -0,0 +1,823 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// independent from idl_parser, since this code is not needed for most clients
+
+#include <string>
+
+#include "flatbuffers/code_generators.h"
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+#include <unordered_set>
+
+namespace flatbuffers {
+namespace python {
+
+// Hardcode spaces per indentation.
+const CommentConfig def_comment = { nullptr, "#", nullptr };
+const std::string Indent = "    ";
+
+class PythonGenerator : public BaseGenerator {
+ public:
+  PythonGenerator(const Parser &parser, const std::string &path,
+                  const std::string &file_name)
+      : BaseGenerator(parser, path, file_name, "" /* not used */,
+                      "" /* not used */),
+        float_const_gen_("float('nan')", "float('inf')", "float('-inf')") {
+    static const char * const keywords[] = {
+      "False",
+      "None",
+      "True",
+      "and",
+      "as",
+      "assert",
+      "break",
+      "class",
+      "continue",
+      "def",
+      "del",
+      "elif",
+      "else",
+      "except",
+      "finally",
+      "for",
+      "from",
+      "global",
+      "if",
+      "import",
+      "in",
+      "is",
+      "lambda",
+      "nonlocal",
+      "not",
+      "or",
+      "pass",
+      "raise",
+      "return",
+      "try",
+      "while",
+      "with",
+      "yield"
+    };
+    keywords_.insert(std::begin(keywords), std::end(keywords));
+  }
+
+  // Most field accessors need to retrieve and test the field offset first,
+  // this is the prefix code for that.
+  std::string OffsetPrefix(const FieldDef &field) {
+    return "\n" + Indent + Indent +
+          "o = flatbuffers.number_types.UOffsetTFlags.py_type" +
+          "(self._tab.Offset(" + NumToString(field.value.offset) + "))\n" +
+          Indent + Indent + "if o != 0:\n";
+  }
+
+  // Begin a class declaration.
+  void BeginClass(const StructDef &struct_def, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "class " + NormalizedName(struct_def) + "(object):\n";
+    code += Indent + "__slots__ = ['_tab']";
+    code += "\n\n";
+  }
+
+  // Begin enum code with a class declaration.
+  void BeginEnum(const std::string &class_name, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "class " + class_name + "(object):\n";
+  }
+
+  std::string EscapeKeyword(const std::string &name) const {
+    return keywords_.find(name) == keywords_.end() ? name : name + "_";
+  }
+
+  std::string NormalizedName(const Definition &definition) const {
+    return EscapeKeyword(definition.name);
+  }
+
+  std::string NormalizedName(const EnumVal &ev) const {
+    return EscapeKeyword(ev.name);
+  }
+
+  // A single enum member.
+  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 += enum_def.ToString(ev) + "\n";
+  }
+
+  // End enum code.
+  void EndEnum(std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "\n";
+  }
+
+  // Initialize a new struct or table from existing data.
+  void NewRootTypeFromBuffer(const StructDef &struct_def,
+                             std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    code += Indent + "@classmethod\n";
+    code += Indent + "def GetRootAs";
+    code += NormalizedName(struct_def);
+    code += "(cls, buf, offset):";
+    code += "\n";
+    code += Indent + Indent;
+    code += "n = flatbuffers.encode.Get";
+    code += "(flatbuffers.packer.uoffset, buf, offset)\n";
+    code += Indent + Indent + "x = " + NormalizedName(struct_def) + "()\n";
+    code += Indent + Indent + "x.Init(buf, n + offset)\n";
+    code += Indent + Indent + "return x\n";
+    code += "\n";
+  }
+
+  // Initialize an existing object with other data, to avoid an allocation.
+  void InitializeExisting(const StructDef &struct_def,
+                          std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    GenReceiver(struct_def, code_ptr);
+    code += "Init(self, buf, pos):\n";
+    code += Indent + Indent + "self._tab = flatbuffers.table.Table(buf, pos)\n";
+    code += "\n";
+  }
+
+  // Get the length of a vector.
+  void GetVectorLen(const StructDef &struct_def, const FieldDef &field,
+                    std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    GenReceiver(struct_def, code_ptr);
+    code += MakeCamel(NormalizedName(field)) + "Length(self";
+    code += "):" + OffsetPrefix(field);
+    code += Indent + Indent + Indent + "return self._tab.VectorLen(o)\n";
+    code += Indent + Indent + "return 0\n\n";
+  }
+
+  // Get the value of a struct's scalar.
+  void GetScalarFieldOfStruct(const StructDef &struct_def,
+                              const FieldDef &field,
+                              std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    std::string getter = GenGetter(field.value.type);
+    GenReceiver(struct_def, code_ptr);
+    code += MakeCamel(NormalizedName(field));
+    code += "(self): return " + getter;
+    code += "self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(";
+    code += NumToString(field.value.offset) + "))\n";
+  }
+
+  // Get the value of a table's scalar.
+  void GetScalarFieldOfTable(const StructDef &struct_def,
+                             const FieldDef &field,
+                             std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    std::string getter = GenGetter(field.value.type);
+    GenReceiver(struct_def, code_ptr);
+    code += MakeCamel(NormalizedName(field));
+    code += "(self):";
+    code += OffsetPrefix(field);
+    getter += "o + self._tab.Pos)";
+    auto is_bool = IsBool(field.value.type.base_type);
+    if (is_bool) {
+      getter = "bool(" + getter + ")";
+    }
+    code += Indent + Indent + Indent + "return " + getter + "\n";
+    std::string default_value;
+    if (is_bool) {
+      default_value = field.value.constant == "0" ? "False" : "True";
+    } else {
+      default_value = IsFloat(field.value.type.base_type)
+                          ? float_const_gen_.GenFloatConstant(field)
+                          : field.value.constant;
+    }
+    code += Indent + Indent + "return " + default_value + "\n\n";
+  }
+
+  // Get a struct by initializing an existing struct.
+  // Specific to Struct.
+  void GetStructFieldOfStruct(const StructDef &struct_def,
+                              const FieldDef &field,
+                              std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    GenReceiver(struct_def, code_ptr);
+    code += MakeCamel(NormalizedName(field));
+    code += "(self, obj):\n";
+    code += Indent + Indent + "obj.Init(self._tab.Bytes, self._tab.Pos + ";
+    code += NumToString(field.value.offset) + ")";
+    code += "\n" + Indent + Indent + "return obj\n\n";
+  }
+
+  // Get the value of a fixed size array.
+  void GetArrayOfStruct(const StructDef &struct_def, const FieldDef &field,
+                        std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    const auto vec_type = field.value.type.VectorType();
+    GenReceiver(struct_def, code_ptr);
+    code += MakeCamel(NormalizedName(field));
+    if (IsStruct(vec_type)) {
+      code += "(self, obj, i):\n";
+      code += Indent + Indent + "obj.Init(self._tab.Bytes, self._tab.Pos + ";
+      code += NumToString(field.value.offset) + " + i * ";
+      code += NumToString(InlineSize(vec_type));
+      code += ")\n" + Indent + Indent + "return obj\n\n";
+    } else {
+      auto getter = GenGetter(vec_type);
+      code += "(self): return [" + getter;
+      code += "self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(";
+      code += NumToString(field.value.offset) + " + i * ";
+      code += NumToString(InlineSize(vec_type));
+      code += ")) for i in range(";
+      code += NumToString(field.value.type.fixed_length) + ")]\n";
+    }
+  }
+
+  // Get a struct by initializing an existing struct.
+  // Specific to Table.
+  void GetStructFieldOfTable(const StructDef &struct_def,
+                             const FieldDef &field,
+                             std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    GenReceiver(struct_def, code_ptr);
+    code += MakeCamel(NormalizedName(field));
+    code += "(self):";
+    code += OffsetPrefix(field);
+    if (field.value.type.struct_def->fixed) {
+      code += Indent + Indent + Indent + "x = o + self._tab.Pos\n";
+    } else {
+      code += Indent + Indent + Indent;
+      code += "x = self._tab.Indirect(o + self._tab.Pos)\n";
+    }
+    code += Indent + Indent + Indent;
+    code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n";
+    code += Indent + Indent + Indent + "obj = " + TypeName(field) + "()\n";
+    code += Indent + Indent + Indent + "obj.Init(self._tab.Bytes, x)\n";
+    code += Indent + Indent + Indent + "return obj\n";
+    code += Indent + Indent + "return None\n\n";
+  }
+
+  // Get the value of a string.
+  void GetStringField(const StructDef &struct_def, const FieldDef &field,
+                      std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    GenReceiver(struct_def, code_ptr);
+    code += MakeCamel(NormalizedName(field));
+    code += "(self):";
+    code += OffsetPrefix(field);
+    code += Indent + Indent + Indent + "return " + GenGetter(field.value.type);
+    code += "o + self._tab.Pos)\n";
+    code += Indent + Indent + "return None\n\n";
+  }
+
+  // Get the value of a union from an object.
+  void GetUnionField(const StructDef &struct_def, const FieldDef &field,
+                     std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    GenReceiver(struct_def, code_ptr);
+    code += MakeCamel(NormalizedName(field)) + "(self):";
+    code += OffsetPrefix(field);
+
+    // TODO(rw): this works and is not the good way to it:
+    bool is_native_table = TypeName(field) == "*flatbuffers.Table";
+    if (is_native_table) {
+      code += Indent + Indent + Indent + "from flatbuffers.table import Table\n";
+    } else {
+      code += Indent + Indent + Indent;
+      code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n";
+    }
+    code += Indent + Indent + Indent + "obj = Table(bytearray(), 0)\n";
+    code += Indent + Indent + Indent + GenGetter(field.value.type);
+    code += "obj, o)\n" + Indent + Indent + Indent + "return obj\n";
+    code += Indent + Indent + "return None\n\n";
+  }
+
+  // Get the value of a vector's struct member.
+  void GetMemberOfVectorOfStruct(const StructDef &struct_def,
+                                 const FieldDef &field,
+                                 std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    auto vectortype = field.value.type.VectorType();
+
+    GenReceiver(struct_def, code_ptr);
+    code += MakeCamel(NormalizedName(field));
+    code += "(self, j):" + OffsetPrefix(field);
+    code += Indent + Indent + Indent + "x = self._tab.Vector(o)\n";
+    code += Indent + Indent + Indent;
+    code += "x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * ";
+    code += NumToString(InlineSize(vectortype)) + "\n";
+    if (!(vectortype.struct_def->fixed)) {
+      code += Indent + Indent + Indent + "x = self._tab.Indirect(x)\n";
+    }
+    code += Indent + Indent + Indent;
+    code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n";
+    code += Indent + Indent + Indent + "obj = " + TypeName(field) + "()\n";
+    code += Indent + Indent + Indent + "obj.Init(self._tab.Bytes, x)\n";
+    code += Indent + Indent + Indent + "return obj\n";
+    code += Indent + Indent + "return None\n\n";
+  }
+
+  // Get the value of a vector's non-struct member. Uses a named return
+  // argument to conveniently set the zero value for the result.
+  void GetMemberOfVectorOfNonStruct(const StructDef &struct_def,
+                                    const FieldDef &field,
+                                    std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    auto vectortype = field.value.type.VectorType();
+
+    GenReceiver(struct_def, code_ptr);
+    code += MakeCamel(NormalizedName(field));
+    code += "(self, j):";
+    code += OffsetPrefix(field);
+    code += Indent + Indent + Indent + "a = self._tab.Vector(o)\n";
+    code += Indent + Indent + Indent;
+    code += "return " + GenGetter(field.value.type);
+    code += "a + flatbuffers.number_types.UOffsetTFlags.py_type(j * ";
+    code += NumToString(InlineSize(vectortype)) + "))\n";
+    if (vectortype.base_type == BASE_TYPE_STRING) {
+      code += Indent + Indent + "return \"\"\n";
+    } else {
+      code += Indent + Indent + "return 0\n";
+    }
+    code += "\n";
+  }
+
+  // Returns a non-struct vector as a numpy array. Much faster
+  // than iterating over the vector element by element.
+  void GetVectorOfNonStructAsNumpy(const StructDef &struct_def,
+                                   const FieldDef &field,
+                                   std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    auto vectortype = field.value.type.VectorType();
+
+    // Currently, we only support accessing as numpy array if
+    // the vector type is a scalar.
+    if (!(IsScalar(vectortype.base_type))) { return; }
+
+    GenReceiver(struct_def, code_ptr);
+    code += MakeCamel(NormalizedName(field)) + "AsNumpy(self):";
+    code += OffsetPrefix(field);
+
+    code += Indent + Indent + Indent;
+    code += "return ";
+    code += "self._tab.GetVectorAsNumpy(flatbuffers.number_types.";
+    code += MakeCamel(GenTypeGet(field.value.type));
+    code += "Flags, o)\n";
+
+    if (vectortype.base_type == BASE_TYPE_STRING) {
+      code += Indent + Indent + "return \"\"\n";
+    } else {
+      code += Indent + Indent + "return 0\n";
+    }
+    code += "\n";
+  }
+
+  // Begin the creator function signature.
+  void BeginBuilderArgs(const StructDef &struct_def,
+                        std::string *code_ptr) {
+    std::string &code = *code_ptr;
+
+    code += "\n";
+    code += "def Create" + NormalizedName(struct_def);
+    code += "(builder";
+  }
+
+  // Recursively generate arguments for a constructor, to deal with nested
+  // structs.
+  void StructBuilderArgs(const StructDef &struct_def,
+                         const char *nameprefix, std::string *code_ptr) {
+    for (auto it = struct_def.fields.vec.begin();
+        it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      const auto &field_type = field.value.type;
+      const auto &type =
+          IsArray(field_type) ? field_type.VectorType() : field_type;
+      if (IsStruct(type)) {
+        // Generate arguments for a struct inside a struct. To ensure names
+        // don't clash, and to make it obvious these arguments are constructing
+        // a nested struct, prefix the name with the field name.
+        StructBuilderArgs(*field_type.struct_def,
+                          (nameprefix + (NormalizedName(field) + "_")).c_str(),
+                          code_ptr);
+      } else {
+        std::string &code = *code_ptr;
+        code += std::string(", ") + nameprefix;
+        code += MakeCamel(NormalizedName(field), false);
+      }
+    }
+  }
+
+  // End the creator function signature.
+  void EndBuilderArgs(std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "):\n";
+  }
+
+  // Recursively generate struct construction statements and instert manual
+  // padding.
+  void StructBuilderBody(const StructDef &struct_def, const char *nameprefix,
+                         std::string *code_ptr, size_t index = 0,
+                         bool in_array = false) {
+    std::string &code = *code_ptr;
+    std::string indent(index * 4, ' ');
+    code +=
+        indent + "    builder.Prep(" + NumToString(struct_def.minalign) + ", ";
+    code += NumToString(struct_def.bytesize) + ")\n";
+    for (auto it = struct_def.fields.vec.rbegin();
+        it != struct_def.fields.vec.rend(); ++it) {
+      auto &field = **it;
+      const auto &field_type = field.value.type;
+      const auto &type =
+          IsArray(field_type) ? field_type.VectorType() : field_type;
+      if (field.padding)
+        code +=
+            indent + "    builder.Pad(" + NumToString(field.padding) + ")\n";
+      if (IsStruct(field_type)) {
+        StructBuilderBody(*field_type.struct_def,
+                          (nameprefix + (NormalizedName(field) + "_")).c_str(),
+                          code_ptr, index, in_array);
+      } else {
+        const auto index_var = "_idx" + NumToString(index);
+        if (IsArray(field_type)) {
+          code += indent + "    for " + index_var + " in range(";
+          code += NumToString(field_type.fixed_length);
+          code += " , 0, -1):\n";
+          in_array = true;
+        }
+        if (IsStruct(type)) {
+          StructBuilderBody(
+              *field_type.struct_def,
+              (nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr,
+              index + 1, in_array);
+        } else {
+          code += IsArray(field_type) ? "    " : "";
+          code += indent + "    builder.Prepend" + GenMethod(field) + "(";
+          code += nameprefix + MakeCamel(NormalizedName(field), false);
+          size_t array_cnt = index + (IsArray(field_type) ? 1 : 0);
+          for (size_t i = 0; in_array && i < array_cnt; i++) {
+            code += "[_idx" + NumToString(i) + "-1]";
+          }
+          code += ")\n";
+        }
+      }
+    }
+  }
+
+  void EndBuilderBody(std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "    return builder.Offset()\n";
+  }
+
+  // Get the value of a table's starting offset.
+  void GetStartOfTable(const StructDef &struct_def,
+                       std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "def " + NormalizedName(struct_def) + "Start";
+    code += "(builder): ";
+    code += "builder.StartObject(";
+    code += NumToString(struct_def.fields.vec.size());
+    code += ")\n";
+  }
+
+  // Set the value of a table's field.
+  void BuildFieldOfTable(const StructDef &struct_def,
+                         const FieldDef &field, const size_t offset,
+                         std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "def " + NormalizedName(struct_def) + "Add" + MakeCamel(NormalizedName(field));
+    code += "(builder, ";
+    code += MakeCamel(NormalizedName(field), false);
+    code += "): ";
+    code += "builder.Prepend";
+    code += GenMethod(field) + "Slot(";
+    code += NumToString(offset) + ", ";
+    if (!IsScalar(field.value.type.base_type) && (!struct_def.fixed)) {
+      code += "flatbuffers.number_types.UOffsetTFlags.py_type";
+      code += "(";
+      code += MakeCamel(NormalizedName(field), false) + ")";
+    } else {
+      code += MakeCamel(NormalizedName(field), false);
+    }
+    code += ", ";
+    code += IsFloat(field.value.type.base_type)
+                ? float_const_gen_.GenFloatConstant(field)
+                : field.value.constant;
+    code += ")\n";
+  }
+
+  // Set the value of one of the members of a table's vector.
+  void BuildVectorOfTable(const StructDef &struct_def,
+                          const FieldDef &field, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "def " + NormalizedName(struct_def) + "Start";
+    code += MakeCamel(NormalizedName(field));
+    code += "Vector(builder, numElems): return builder.StartVector(";
+    auto vector_type = field.value.type.VectorType();
+    auto alignment = InlineAlignment(vector_type);
+    auto elem_size = InlineSize(vector_type);
+    code += NumToString(elem_size);
+    code += ", numElems, " + NumToString(alignment);
+    code += ")\n";
+  }
+
+  // Get the offset of the end of a table.
+  void GetEndOffsetOnTable(const StructDef &struct_def,
+                           std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += "def " + NormalizedName(struct_def) + "End";
+    code += "(builder): ";
+    code += "return builder.EndObject()\n";
+  }
+
+  // Generate the receiver for function signatures.
+  void GenReceiver(const StructDef &struct_def, std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code += Indent + "# " + NormalizedName(struct_def) + "\n";
+    code += Indent + "def ";
+  }
+
+  // Generate a struct field, conditioned on its child type(s).
+  void GenStructAccessor(const StructDef &struct_def,
+                         const FieldDef &field, std::string *code_ptr) {
+    GenComment(field.doc_comment, code_ptr, &def_comment, Indent.c_str());
+    if (IsScalar(field.value.type.base_type)) {
+      if (struct_def.fixed) {
+        GetScalarFieldOfStruct(struct_def, field, code_ptr);
+      } else {
+        GetScalarFieldOfTable(struct_def, field, code_ptr);
+      }
+    } else if (IsArray(field.value.type)) {
+      GetArrayOfStruct(struct_def, field, code_ptr);
+    } else {
+      switch (field.value.type.base_type) {
+        case BASE_TYPE_STRUCT:
+          if (struct_def.fixed) {
+            GetStructFieldOfStruct(struct_def, field, code_ptr);
+          } else {
+            GetStructFieldOfTable(struct_def, field, code_ptr);
+          }
+          break;
+        case BASE_TYPE_STRING: GetStringField(struct_def, field, code_ptr); break;
+        case BASE_TYPE_VECTOR: {
+          auto vectortype = field.value.type.VectorType();
+          if (vectortype.base_type == BASE_TYPE_STRUCT) {
+            GetMemberOfVectorOfStruct(struct_def, field, code_ptr);
+          } else {
+            GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr);
+            GetVectorOfNonStructAsNumpy(struct_def, field, code_ptr);
+          }
+          break;
+        }
+        case BASE_TYPE_UNION: GetUnionField(struct_def, field, code_ptr); break;
+        default: FLATBUFFERS_ASSERT(0);
+      }
+    }
+    if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+      GetVectorLen(struct_def, field, code_ptr);
+    }
+  }
+
+  // Generate table constructors, conditioned on its members' types.
+  void GenTableBuilders(const StructDef &struct_def,
+                        std::string *code_ptr) {
+    GetStartOfTable(struct_def, code_ptr);
+
+    for (auto it = struct_def.fields.vec.begin();
+        it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+
+      auto offset = it - struct_def.fields.vec.begin();
+      BuildFieldOfTable(struct_def, field, offset, code_ptr);
+      if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+        BuildVectorOfTable(struct_def, field, code_ptr);
+      }
+    }
+
+    GetEndOffsetOnTable(struct_def, code_ptr);
+  }
+
+  // Generate function to check for proper file identifier
+  void GenHasFileIdentifier(const StructDef &struct_def,
+                            std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    std::string escapedID;
+    // In the event any of file_identifier characters are special(NULL, \, etc),
+    // problems occur. To prevent this, convert all chars to their hex-escaped
+    // equivalent.
+    for (auto it = parser_.file_identifier_.begin();
+         it != parser_.file_identifier_.end(); ++it) {
+      escapedID += "\\x" + IntToStringHex(*it, 2);
+    }
+
+    code += Indent + "@classmethod\n";
+    code += Indent + "def " + NormalizedName(struct_def);
+    code += "BufferHasIdentifier(cls, buf, offset, size_prefixed=False):";
+    code += "\n";
+    code += Indent + Indent;
+    code += "return flatbuffers.util.BufferHasIdentifier(buf, offset, b\"";
+    code += escapedID;
+    code += "\", size_prefixed=size_prefixed)\n";
+    code += "\n";
+  }
+  
+  // Generate struct or table methods.
+  void GenStruct(const StructDef &struct_def, std::string *code_ptr) {
+    if (struct_def.generated) return;
+
+    GenComment(struct_def.doc_comment, code_ptr, &def_comment);
+    BeginClass(struct_def, code_ptr);
+    if (!struct_def.fixed) {
+      // Generate a special accessor for the table that has been declared as
+      // the root type.
+      NewRootTypeFromBuffer(struct_def, code_ptr);
+      if (parser_.file_identifier_.length()){
+        // Generate a special function to test file_identifier
+        GenHasFileIdentifier(struct_def, code_ptr);
+      }
+    }
+    // Generate the Init method that sets the field in a pre-existing
+    // accessor object. This is to allow object reuse.
+    InitializeExisting(struct_def, code_ptr);
+    for (auto it = struct_def.fields.vec.begin();
+        it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+
+      GenStructAccessor(struct_def, field, code_ptr);
+    }
+
+    if (struct_def.fixed) {
+      // create a struct constructor function
+      GenStructBuilder(struct_def, code_ptr);
+    } else {
+      // Create a set of functions that allow table construction.
+      GenTableBuilders(struct_def, code_ptr);
+    }
+  }
+
+  // Generate enum declarations.
+  void GenEnum(const EnumDef &enum_def, std::string *code_ptr) {
+    if (enum_def.generated) return;
+
+    GenComment(enum_def.doc_comment, code_ptr, &def_comment);
+    BeginEnum(NormalizedName(enum_def), code_ptr);
+    for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
+      auto &ev = **it;
+      GenComment(ev.doc_comment, code_ptr, &def_comment, Indent.c_str());
+      EnumMember(enum_def, ev, code_ptr);
+    }
+    EndEnum(code_ptr);
+  }
+
+  // Returns the function name that is able to read a value of the given type.
+  std::string GenGetter(const Type &type) {
+    switch (type.base_type) {
+      case BASE_TYPE_STRING: return "self._tab.String(";
+      case BASE_TYPE_UNION: return "self._tab.Union(";
+      case BASE_TYPE_VECTOR: return GenGetter(type.VectorType());
+      default:
+        return "self._tab.Get(flatbuffers.number_types." +
+              MakeCamel(GenTypeGet(type)) + "Flags, ";
+    }
+  }
+
+  // Returns the method name for use with add/put calls.
+  std::string GenMethod(const FieldDef &field) {
+    return (IsScalar(field.value.type.base_type) || IsArray(field.value.type))
+               ? MakeCamel(GenTypeBasic(field.value.type))
+               : (IsStruct(field.value.type) ? "Struct" : "UOffsetTRelative");
+  }
+
+  std::string GenTypeBasic(const Type &type) {
+    static const char *ctypename[] = {
+    // clang-format off
+      #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+        CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
+        #PTYPE,
+        FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+      #undef FLATBUFFERS_TD
+      // clang-format on
+    };
+    return ctypename[IsArray(type) ? type.VectorType().base_type
+                                   : type.base_type];
+  }
+
+  std::string GenTypePointer(const Type &type) {
+    switch (type.base_type) {
+      case BASE_TYPE_STRING: return "string";
+      case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType());
+      case BASE_TYPE_STRUCT: return type.struct_def->name;
+      case BASE_TYPE_UNION:
+        // fall through
+      default: return "*flatbuffers.Table";
+    }
+  }
+
+  std::string GenTypeGet(const Type &type) {
+    return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type);
+  }
+
+  std::string TypeName(const FieldDef &field) {
+    return GenTypeGet(field.value.type);
+  }
+
+  // Create a struct with a builder and the struct's arguments.
+  void GenStructBuilder(const StructDef &struct_def,
+                              std::string *code_ptr) {
+    BeginBuilderArgs(struct_def, code_ptr);
+    StructBuilderArgs(struct_def, "", code_ptr);
+    EndBuilderArgs(code_ptr);
+
+    StructBuilderBody(struct_def, "", code_ptr);
+    EndBuilderBody(code_ptr);
+  }
+
+  bool generate() {
+    if (!generateEnums()) return false;
+    if (!generateStructs()) return false;
+    return true;
+  }
+
+ private:
+  bool generateEnums() {
+    for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
+         ++it) {
+      auto &enum_def = **it;
+      std::string enumcode;
+      GenEnum(enum_def, &enumcode);
+      if (!SaveType(enum_def, enumcode, false)) return false;
+    }
+    return true;
+  }
+
+  bool generateStructs() {
+    for (auto it = parser_.structs_.vec.begin();
+         it != parser_.structs_.vec.end(); ++it) {
+      auto &struct_def = **it;
+      std::string declcode;
+      GenStruct(struct_def, &declcode);
+      if (!SaveType(struct_def, declcode, true)) return false;
+    }
+    return true;
+  }
+
+  // Begin by declaring namespace and imports.
+  void BeginFile(const std::string &name_space_name, const bool needs_imports,
+                 std::string *code_ptr) {
+    std::string &code = *code_ptr;
+    code = code + "# " + FlatBuffersGeneratedWarning() + "\n\n";
+    code += "# namespace: " + name_space_name + "\n\n";
+    if (needs_imports) { code += "import flatbuffers\n\n"; }
+  }
+
+  // Save out the generated code for a Python Table type.
+  bool SaveType(const Definition &def, const std::string &classcode,
+                bool needs_imports) {
+    if (!classcode.length()) return true;
+
+    std::string namespace_dir = path_;
+    auto &namespaces = def.defined_namespace->components;
+    for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
+      if (it != namespaces.begin()) namespace_dir += kPathSeparator;
+      namespace_dir += *it;
+      std::string init_py_filename = namespace_dir + "/__init__.py";
+      SaveFile(init_py_filename.c_str(), "", false);
+    }
+
+    std::string code = "";
+    BeginFile(LastNamespacePart(*def.defined_namespace), needs_imports, &code);
+    code += classcode;
+    std::string filename =
+        NamespaceDir(*def.defined_namespace) + NormalizedName(def) + ".py";
+    return SaveFile(filename.c_str(), code, false);
+  }
+ private:
+  std::unordered_set<std::string> keywords_;
+  const SimpleFloatConstantGenerator float_const_gen_;
+};
+
+}  // namespace python
+
+bool GeneratePython(const Parser &parser, const std::string &path,
+                    const std::string &file_name) {
+  python::PythonGenerator generator(parser, path, file_name);
+  return generator.generate();
+}
+
+}  // namespace flatbuffers
diff --git a/src/idl_gen_rust.cpp b/src/idl_gen_rust.cpp
new file mode 100644
index 0000000..936ac83
--- /dev/null
+++ b/src/idl_gen_rust.cpp
@@ -0,0 +1,1825 @@
+/*
+ * Copyright 2018 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// independent from idl_parser, since this code is not needed for most clients
+
+#include "flatbuffers/code_generators.h"
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+namespace flatbuffers {
+
+static std::string GeneratedFileName(const std::string &path,
+                                     const std::string &file_name) {
+  return path + file_name + "_generated.rs";
+}
+
+// Convert a camelCaseIdentifier or CamelCaseIdentifier to a
+// snake_case_indentifier.
+std::string MakeSnakeCase(const std::string &in) {
+  std::string s;
+  for (size_t i = 0; i < in.length(); i++) {
+    if (i == 0) {
+      s += static_cast<char>(tolower(in[0]));
+    } else if (in[i] == '_') {
+      s += '_';
+    } else if (!islower(in[i])) {
+      // Prevent duplicate underscores for Upper_Snake_Case strings
+      // and UPPERCASE strings.
+      if (islower(in[i - 1])) {
+        s += '_';
+      }
+      s += static_cast<char>(tolower(in[i]));
+    } else {
+      s += in[i];
+    }
+  }
+  return s;
+}
+
+// Convert a string to all uppercase.
+std::string MakeUpper(const std::string &in) {
+  std::string s;
+  for (size_t i = 0; i < in.length(); i++) {
+    s += static_cast<char>(toupper(in[i]));
+  }
+  return s;
+}
+
+// Encapsulate all logical field types in this enum. This allows us to write
+// field logic based on type switches, instead of branches on the properties
+// set on the Type.
+// TODO(rw): for backwards compatibility, we can't use a strict `enum class`
+//           declaration here. could we use the `-Wswitch-enum` warning to
+//           achieve the same effect?
+enum FullType {
+  ftInteger = 0,
+  ftFloat = 1,
+  ftBool = 2,
+
+  ftStruct = 3,
+  ftTable = 4,
+
+  ftEnumKey = 5,
+  ftUnionKey = 6,
+
+  ftUnionValue = 7,
+
+  // TODO(rw): bytestring?
+  ftString = 8,
+
+  ftVectorOfInteger = 9,
+  ftVectorOfFloat = 10,
+  ftVectorOfBool = 11,
+  ftVectorOfEnumKey = 12,
+  ftVectorOfStruct = 13,
+  ftVectorOfTable = 14,
+  ftVectorOfString = 15,
+  ftVectorOfUnionValue = 16,
+};
+
+// Convert a Type to a FullType (exhaustive).
+FullType GetFullType(const Type &type) {
+  // N.B. The order of these conditionals matters for some types.
+
+  if (type.base_type == BASE_TYPE_STRING) {
+    return ftString;
+  } else if (type.base_type == BASE_TYPE_STRUCT) {
+    if (type.struct_def->fixed) {
+      return ftStruct;
+    } else {
+      return ftTable;
+    }
+  } else if (type.base_type == BASE_TYPE_VECTOR) {
+    switch (GetFullType(type.VectorType())) {
+      case ftInteger: {
+        return ftVectorOfInteger;
+      }
+      case ftFloat: {
+        return ftVectorOfFloat;
+      }
+      case ftBool: {
+        return ftVectorOfBool;
+      }
+      case ftStruct: {
+        return ftVectorOfStruct;
+      }
+      case ftTable: {
+        return ftVectorOfTable;
+      }
+      case ftString: {
+        return ftVectorOfString;
+      }
+      case ftEnumKey: {
+        return ftVectorOfEnumKey;
+      }
+      case ftUnionKey:
+      case ftUnionValue: {
+        FLATBUFFERS_ASSERT(false && "vectors of unions are unsupported");
+        break;
+      }
+      default: {
+        FLATBUFFERS_ASSERT(false && "vector of vectors are unsupported");
+      }
+    }
+  } else if (type.enum_def != nullptr) {
+    if (type.enum_def->is_union) {
+      if (type.base_type == BASE_TYPE_UNION) {
+        return ftUnionValue;
+      } else if (IsInteger(type.base_type)) {
+        return ftUnionKey;
+      } else {
+        FLATBUFFERS_ASSERT(false && "unknown union field type");
+      }
+    } else {
+      return ftEnumKey;
+    }
+  } else if (IsScalar(type.base_type)) {
+    if (IsBool(type.base_type)) {
+      return ftBool;
+    } else if (IsInteger(type.base_type)) {
+      return ftInteger;
+    } else if (IsFloat(type.base_type)) {
+      return ftFloat;
+    } else {
+      FLATBUFFERS_ASSERT(false && "unknown number type");
+    }
+  }
+
+  FLATBUFFERS_ASSERT(false && "completely unknown type");
+
+  // this is only to satisfy the compiler's return analysis.
+  return ftBool;
+}
+
+// If the second parameter is false then wrap the first with Option<...>
+std::string WrapInOptionIfNotRequired(std::string s, bool required) {
+  if (required) {
+    return s;
+  } else {
+    return "Option<" + s + ">";
+  }
+}
+
+// If the second parameter is false then add .unwrap()
+std::string AddUnwrapIfRequired(std::string s, bool required) {
+  if (required) {
+    return s + ".unwrap()";
+  } else {
+    return s;
+  }
+}
+
+namespace rust {
+
+class RustGenerator : public BaseGenerator {
+ public:
+  RustGenerator(const Parser &parser, const std::string &path,
+                const std::string &file_name)
+      : BaseGenerator(parser, path, file_name, "", "::"),
+        cur_name_space_(nullptr) {
+    const char *keywords[] = {
+      // list taken from:
+      // https://doc.rust-lang.org/book/second-edition/appendix-01-keywords.html
+      //
+      // we write keywords one per line so that we can easily compare them with
+      // changes to that webpage in the future.
+
+      // currently-used keywords
+      "as",
+      "break",
+      "const",
+      "continue",
+      "crate",
+      "else",
+      "enum",
+      "extern",
+      "false",
+      "fn",
+      "for",
+      "if",
+      "impl",
+      "in",
+      "let",
+      "loop",
+      "match",
+      "mod",
+      "move",
+      "mut",
+      "pub",
+      "ref",
+      "return",
+      "Self",
+      "self",
+      "static",
+      "struct",
+      "super",
+      "trait",
+      "true",
+      "type",
+      "unsafe",
+      "use",
+      "where",
+      "while",
+
+      // future possible keywords
+      "abstract",
+      "alignof",
+      "become",
+      "box",
+      "do",
+      "final",
+      "macro",
+      "offsetof",
+      "override",
+      "priv",
+      "proc",
+      "pure",
+      "sizeof",
+      "typeof",
+      "unsized",
+      "virtual",
+      "yield",
+
+      // other rust terms we should not use
+      "std",
+      "usize",
+      "isize",
+      "u8",
+      "i8",
+      "u16",
+      "i16",
+      "u32",
+      "i32",
+      "u64",
+      "i64",
+      "u128",
+      "i128",
+      "f32",
+      "f64",
+
+      // These are terms the code generator can implement on types.
+      //
+      // In Rust, the trait resolution rules (as described at
+      // https://github.com/rust-lang/rust/issues/26007) mean that, as long
+      // as we impl table accessors as inherent methods, we'll never create
+      // conflicts with these keywords. However, that's a fairly nuanced
+      // implementation detail, and how we implement methods could change in
+      // the future. as a result, we proactively block these out as reserved
+      // words.
+      "follow",
+      "push",
+      "size",
+      "alignment",
+      "to_little_endian",
+      "from_little_endian",
+      nullptr };
+    for (auto kw = keywords; *kw; kw++) keywords_.insert(*kw);
+  }
+
+  // Iterate through all definitions we haven't generated code for (enums,
+  // structs, and tables) and output them to a single file.
+  bool generate() {
+    code_.Clear();
+    code_ += "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n";
+
+    assert(!cur_name_space_);
+
+    // Generate imports for the global scope in case no namespace is used
+    // in the schema file.
+    GenNamespaceImports(0);
+    code_ += "";
+
+    // Generate all code in their namespaces, once, because Rust does not
+    // permit re-opening modules.
+    //
+    // TODO(rw): Use a set data structure to reduce namespace evaluations from
+    //           O(n**2) to O(n).
+    for (auto ns_it = parser_.namespaces_.begin();
+         ns_it != parser_.namespaces_.end();
+         ++ns_it) {
+      const auto &ns = *ns_it;
+
+      // Generate code for all the enum declarations.
+      for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
+           ++it) {
+        const auto &enum_def = **it;
+        if (enum_def.defined_namespace != ns) { continue; }
+        if (!enum_def.generated) {
+          SetNameSpace(enum_def.defined_namespace);
+          GenEnum(enum_def);
+        }
+      }
+
+      // Generate code for all structs.
+      for (auto it = parser_.structs_.vec.begin();
+           it != parser_.structs_.vec.end(); ++it) {
+        const auto &struct_def = **it;
+        if (struct_def.defined_namespace != ns) { continue; }
+        if (struct_def.fixed && !struct_def.generated) {
+          SetNameSpace(struct_def.defined_namespace);
+          GenStruct(struct_def);
+        }
+      }
+
+      // Generate code for all tables.
+      for (auto it = parser_.structs_.vec.begin();
+           it != parser_.structs_.vec.end(); ++it) {
+        const auto &struct_def = **it;
+        if (struct_def.defined_namespace != ns) { continue; }
+        if (!struct_def.fixed && !struct_def.generated) {
+          SetNameSpace(struct_def.defined_namespace);
+          GenTable(struct_def);
+        }
+      }
+
+      // Generate global helper functions.
+      if (parser_.root_struct_def_) {
+        auto &struct_def = *parser_.root_struct_def_;
+        if (struct_def.defined_namespace != ns) { continue; }
+        SetNameSpace(struct_def.defined_namespace);
+        GenRootTableFuncs(struct_def);
+      }
+    }
+    if (cur_name_space_) SetNameSpace(nullptr);
+
+    const auto file_path = GeneratedFileName(path_, file_name_);
+    const auto final_code = code_.ToString();
+    return SaveFile(file_path.c_str(), final_code, false);
+  }
+
+ private:
+  CodeWriter code_;
+
+  std::set<std::string> keywords_;
+
+  // This tracks the current namespace so we can insert namespace declarations.
+  const Namespace *cur_name_space_;
+
+  const Namespace *CurrentNameSpace() const { return cur_name_space_; }
+
+  // Determine if a Type needs a lifetime template parameter when used in the
+  // Rust builder args.
+  bool TableBuilderTypeNeedsLifetime(const Type &type) const {
+    switch (GetFullType(type)) {
+      case ftInteger:
+      case ftFloat:
+      case ftBool:
+      case ftEnumKey:
+      case ftUnionKey:
+      case ftUnionValue: { return false; }
+      default: { return true; }
+    }
+  }
+
+  // Determine if a table args rust type needs a lifetime template parameter.
+  bool TableBuilderArgsNeedsLifetime(const StructDef &struct_def) const {
+    FLATBUFFERS_ASSERT(!struct_def.fixed);
+
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+      if (field.deprecated) {
+        continue;
+      }
+
+      if (TableBuilderTypeNeedsLifetime(field.value.type)) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  // Determine if a Type needs to be copied (for endian safety) when used in a
+  // Struct.
+  bool StructMemberAccessNeedsCopy(const Type &type) const {
+    switch (GetFullType(type)) {
+      case ftInteger:  // requires endian swap
+      case ftFloat: // requires endian swap
+      case ftBool: // no endian-swap, but do the copy for UX consistency
+      case ftEnumKey: { return true; } // requires endian swap
+      case ftStruct: { return false; } // no endian swap
+      default: {
+        // logic error: no other types can be struct members.
+        FLATBUFFERS_ASSERT(false && "invalid struct member type");
+        return false; // only to satisfy compiler's return analysis
+      }
+    }
+  }
+
+  std::string EscapeKeyword(const std::string &name) const {
+    return keywords_.find(name) == keywords_.end() ? name : name + "_";
+  }
+
+  std::string Name(const Definition &def) const {
+    return EscapeKeyword(def.name);
+  }
+
+  std::string Name(const EnumVal &ev) const { return EscapeKeyword(ev.name); }
+
+  std::string WrapInNameSpace(const Definition &def) const {
+    return WrapInNameSpace(def.defined_namespace, Name(def));
+  }
+  std::string WrapInNameSpace(const Namespace *ns,
+                              const std::string &name) const {
+    if (CurrentNameSpace() == ns) return name;
+    std::string prefix = GetRelativeNamespaceTraversal(CurrentNameSpace(), ns);
+    return prefix + name;
+  }
+
+  // Determine the namespace traversal needed from the Rust crate root.
+  // This may be useful in the future for referring to included files, but is
+  // currently unused.
+  std::string GetAbsoluteNamespaceTraversal(const Namespace *dst) const {
+    std::stringstream stream;
+
+    stream << "::";
+    for (auto d = dst->components.begin(); d != dst->components.end(); ++d) {
+      stream << MakeSnakeCase(*d) + "::";
+    }
+    return stream.str();
+  }
+
+  // Determine the relative namespace traversal needed to reference one
+  // namespace from another namespace. This is useful because it does not force
+  // the user to have a particular file layout. (If we output absolute
+  // namespace paths, that may require users to organize their Rust crates in a
+  // particular way.)
+  std::string GetRelativeNamespaceTraversal(const Namespace *src,
+                                            const Namespace *dst) const {
+    // calculate the path needed to reference dst from src.
+    // example: f(A::B::C, A::B::C) -> (none)
+    // example: f(A::B::C, A::B)    -> super::
+    // example: f(A::B::C, A::B::D) -> super::D
+    // example: f(A::B::C, A)       -> super::super::
+    // example: f(A::B::C, D)       -> super::super::super::D
+    // example: f(A::B::C, D::E)    -> super::super::super::D::E
+    // example: f(A, D::E)          -> super::D::E
+    // does not include leaf object (typically a struct type).
+
+    size_t i = 0;
+    std::stringstream stream;
+
+    auto s = src->components.begin();
+    auto d = dst->components.begin();
+    for(;;) {
+      if (s == src->components.end()) { break; }
+      if (d == dst->components.end()) { break; }
+      if (*s != *d) { break; }
+      ++s;
+      ++d;
+      ++i;
+    }
+
+    for (; s != src->components.end(); ++s) {
+      stream << "super::";
+    }
+    for (; d != dst->components.end(); ++d) {
+      stream << MakeSnakeCase(*d) + "::";
+    }
+    return stream.str();
+  }
+
+  // Generate a comment from the schema.
+  void GenComment(const std::vector<std::string> &dc, const char *prefix = "") {
+    std::string text;
+    ::flatbuffers::GenComment(dc, &text, nullptr, prefix);
+    code_ += text + "\\";
+  }
+
+  // Return a Rust type from the table in idl.h.
+  std::string GetTypeBasic(const Type &type) const {
+    switch (GetFullType(type)) {
+      case ftInteger:
+      case ftFloat:
+      case ftBool:
+      case ftEnumKey:
+      case ftUnionKey: { break; }
+      default: { FLATBUFFERS_ASSERT(false && "incorrect type given");}
+    }
+
+    // clang-format off
+    static const char * const ctypename[] = {
+    #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
+                           RTYPE, KTYPE) \
+            #RTYPE,
+        FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+    #undef FLATBUFFERS_TD
+      // clang-format on
+    };
+
+    if (type.enum_def) { return WrapInNameSpace(*type.enum_def); }
+    return ctypename[type.base_type];
+  }
+
+  // Look up the native type for an enum. This will always be an integer like
+  // u8, i32, etc.
+  std::string GetEnumTypeForDecl(const Type &type) {
+    const auto ft = GetFullType(type);
+    if (!(ft == ftEnumKey || ft == ftUnionKey)) {
+      FLATBUFFERS_ASSERT(false && "precondition failed in GetEnumTypeForDecl");
+    }
+
+    static const char *ctypename[] = {
+    // clang-format off
+    #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
+                           RTYPE, KTYPE) \
+            #RTYPE,
+        FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+    #undef FLATBUFFERS_TD
+      // clang-format on
+    };
+
+    // Enums can be bools, but their Rust representation must be a u8, as used
+    // in the repr attribute (#[repr(bool)] is an invalid attribute).
+    if (type.base_type == BASE_TYPE_BOOL) return "u8";
+    return ctypename[type.base_type];
+  }
+
+  // Return a Rust type for any type (scalar, table, struct) specifically for
+  // using a FlatBuffer.
+  std::string GetTypeGet(const Type &type) const {
+    switch (GetFullType(type)) {
+      case ftInteger:
+      case ftFloat:
+      case ftBool:
+      case ftEnumKey:
+      case ftUnionKey: {
+        return GetTypeBasic(type); }
+      case ftTable: {
+        return WrapInNameSpace(type.struct_def->defined_namespace,
+                               type.struct_def->name) + "<'a>"; }
+      default: {
+        return WrapInNameSpace(type.struct_def->defined_namespace,
+                               type.struct_def->name); }
+    }
+  }
+
+  std::string GetEnumValUse(const EnumDef &enum_def,
+                            const EnumVal &enum_val) const {
+    return Name(enum_def) + "::" + Name(enum_val);
+  }
+
+  // Generate an enum declaration,
+  // an enum string lookup table,
+  // an enum match function,
+  // and an enum array of values
+  void GenEnum(const EnumDef &enum_def) {
+    code_.SetValue("ENUM_NAME", Name(enum_def));
+    code_.SetValue("BASE_TYPE", GetEnumTypeForDecl(enum_def.underlying_type));
+
+    GenComment(enum_def.doc_comment);
+    code_ += "#[allow(non_camel_case_types)]";
+    code_ += "#[repr({{BASE_TYPE}})]";
+    code_ += "#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]";
+    code_ += "pub enum " + Name(enum_def) + " {";
+
+    for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
+      const auto &ev = **it;
+
+      GenComment(ev.doc_comment, "  ");
+      code_.SetValue("KEY", Name(ev));
+      code_.SetValue("VALUE", enum_def.ToString(ev));
+      code_ += "  {{KEY}} = {{VALUE}},";
+    }
+    const EnumVal *minv = enum_def.MinValue();
+    const EnumVal *maxv = enum_def.MaxValue();
+    FLATBUFFERS_ASSERT(minv && maxv);
+
+    code_ += "";
+    code_ += "}";
+    code_ += "";
+
+    code_.SetValue("ENUM_NAME", Name(enum_def));
+    code_.SetValue("ENUM_NAME_SNAKE", MakeSnakeCase(Name(enum_def)));
+    code_.SetValue("ENUM_NAME_CAPS", MakeUpper(MakeSnakeCase(Name(enum_def))));
+    code_.SetValue("ENUM_MIN_BASE_VALUE", enum_def.ToString(*minv));
+    code_.SetValue("ENUM_MAX_BASE_VALUE", enum_def.ToString(*maxv));
+
+    // Generate enum constants, and impls for Follow, EndianScalar, and Push.
+    code_ += "const ENUM_MIN_{{ENUM_NAME_CAPS}}: {{BASE_TYPE}} = \\";
+    code_ += "{{ENUM_MIN_BASE_VALUE}};";
+    code_ += "const ENUM_MAX_{{ENUM_NAME_CAPS}}: {{BASE_TYPE}} = \\";
+    code_ += "{{ENUM_MAX_BASE_VALUE}};";
+    code_ += "";
+    code_ += "impl<'a> flatbuffers::Follow<'a> for {{ENUM_NAME}} {";
+    code_ += "  type Inner = Self;";
+    code_ += "  #[inline]";
+    code_ += "  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {";
+    code_ += "    flatbuffers::read_scalar_at::<Self>(buf, loc)";
+    code_ += "  }";
+    code_ += "}";
+    code_ += "";
+    code_ += "impl flatbuffers::EndianScalar for {{ENUM_NAME}} {";
+    code_ += "  #[inline]";
+    code_ += "  fn to_little_endian(self) -> Self {";
+    code_ += "    let n = {{BASE_TYPE}}::to_le(self as {{BASE_TYPE}});";
+    code_ += "    let p = &n as *const {{BASE_TYPE}} as *const {{ENUM_NAME}};";
+    code_ += "    unsafe { *p }";
+    code_ += "  }";
+    code_ += "  #[inline]";
+    code_ += "  fn from_little_endian(self) -> Self {";
+    code_ += "    let n = {{BASE_TYPE}}::from_le(self as {{BASE_TYPE}});";
+    code_ += "    let p = &n as *const {{BASE_TYPE}} as *const {{ENUM_NAME}};";
+    code_ += "    unsafe { *p }";
+    code_ += "  }";
+    code_ += "}";
+    code_ += "";
+    code_ += "impl flatbuffers::Push for {{ENUM_NAME}} {";
+    code_ += "    type Output = {{ENUM_NAME}};";
+    code_ += "    #[inline]";
+    code_ += "    fn push(&self, dst: &mut [u8], _rest: &[u8]) {";
+    code_ += "        flatbuffers::emplace_scalar::<{{ENUM_NAME}}>"
+             "(dst, *self);";
+    code_ += "    }";
+    code_ += "}";
+    code_ += "";
+
+    // Generate an array of all enumeration values.
+    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().begin(); it != enum_def.Vals().end(); ++it) {
+      const auto &ev = **it;
+      auto value = GetEnumValUse(enum_def, ev);
+      auto suffix = *it != enum_def.Vals().back() ? "," : "";
+      code_ += "  " + value + suffix;
+    }
+    code_ += "];";
+    code_ += "";
+
+    // Generate a string table for enum values.
+    // Problem is, if values are very sparse that could generate really big
+    // tables. Ideally in that case we generate a map lookup instead, but for
+    // the moment we simply don't output a table at all.
+    auto range = enum_def.Distance();
+    // Average distance between values above which we consider a table
+    // "too sparse". Change at will.
+    static const uint64_t kMaxSparseness = 5;
+    if (range / static_cast<uint64_t>(enum_def.size()) < kMaxSparseness) {
+      code_ += "#[allow(non_camel_case_types)]";
+      code_ += "const ENUM_NAMES_{{ENUM_NAME_CAPS}}:[&'static str; " +
+               NumToString(range + 1) + "] = [";
+
+      auto val = enum_def.Vals().front();
+      for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
+           ++it) {
+        auto ev = *it;
+        for (auto k = enum_def.Distance(val, ev); k > 1; --k) {
+          code_ += "    \"\",";
+        }
+        val = ev;
+        auto suffix = *it != enum_def.Vals().back() ? "," : "";
+        code_ += "    \"" + Name(*ev) + "\"" + suffix;
+      }
+      code_ += "];";
+      code_ += "";
+
+      code_ +=
+          "pub fn enum_name_{{ENUM_NAME_SNAKE}}(e: {{ENUM_NAME}}) -> "
+          "&'static str {";
+
+      code_ += "  let index = e as {{BASE_TYPE}}\\";
+      if (enum_def.MinValue()->IsNonZero()) {
+        auto vals = GetEnumValUse(enum_def, *enum_def.MinValue());
+        code_ += " - " + vals + " as {{BASE_TYPE}}\\";
+      }
+      code_ += ";";
+
+      code_ += "  ENUM_NAMES_{{ENUM_NAME_CAPS}}[index as usize]";
+      code_ += "}";
+      code_ += "";
+    }
+
+    if (enum_def.is_union) {
+      // Generate tyoesafe offset(s) for unions
+      code_.SetValue("NAME", Name(enum_def));
+      code_.SetValue("UNION_OFFSET_NAME", Name(enum_def) + "UnionTableOffset");
+      code_ += "pub struct {{UNION_OFFSET_NAME}} {}";
+    }
+  }
+
+  std::string GetFieldOffsetName(const FieldDef &field) {
+    return "VT_" + MakeUpper(Name(field));
+  }
+
+  std::string GetDefaultConstant(const FieldDef &field) {
+    return field.value.type.base_type == BASE_TYPE_FLOAT
+               ? field.value.constant + ""
+               : field.value.constant;
+  }
+
+  std::string GetDefaultScalarValue(const FieldDef &field) {
+    switch (GetFullType(field.value.type)) {
+      case ftInteger: { return GetDefaultConstant(field); }
+      case ftFloat: { return GetDefaultConstant(field); }
+      case ftBool: {
+        return field.value.constant == "0" ? "false" : "true";
+      }
+      case ftUnionKey:
+      case ftEnumKey: {
+        auto ev = field.value.type.enum_def->FindByValue(field.value.constant);
+        assert(ev);
+        return WrapInNameSpace(field.value.type.enum_def->defined_namespace,
+                               GetEnumValUse(*field.value.type.enum_def, *ev));
+      }
+
+      // All pointer-ish types have a default value of None, because they are
+      // wrapped in Option.
+      default: { return "None"; }
+    }
+  }
+
+  // Create the return type for fields in the *BuilderArgs structs that are
+  // used to create Tables.
+  //
+  // Note: we could make all inputs to the BuilderArgs be an Option, as well
+  // as all outputs. But, the UX of Flatbuffers is that the user doesn't get to
+  // know if the value is default or not, because there are three ways to
+  // return a default value:
+  // 1) return a stored value that happens to be the default,
+  // 2) return a hardcoded value because the relevant vtable field is not in
+  //    the vtable, or
+  // 3) return a hardcoded value because the vtable field value is set to zero.
+  std::string TableBuilderArgsDefnType(const FieldDef &field,
+                                       const std::string &lifetime) {
+    const Type& type = field.value.type;
+
+    switch (GetFullType(type)) {
+      case ftInteger:
+      case ftFloat:
+      case ftBool: {
+        const auto typname = GetTypeBasic(type);
+        return typname;
+      }
+      case ftStruct: {
+        const auto typname = WrapInNameSpace(*type.struct_def);
+        return "Option<&" + lifetime + " " + typname + ">";
+      }
+      case ftTable: {
+        const auto typname = WrapInNameSpace(*type.struct_def);
+        return "Option<flatbuffers::WIPOffset<" + typname + "<" + lifetime + \
+               ">>>";
+      }
+      case ftString: {
+        return "Option<flatbuffers::WIPOffset<&" + lifetime + " str>>";
+      }
+      case ftEnumKey:
+      case ftUnionKey: {
+        const auto typname = WrapInNameSpace(*type.enum_def);
+        return typname;
+      }
+      case ftUnionValue: {
+        return "Option<flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>>";
+      }
+
+      case ftVectorOfInteger:
+      case ftVectorOfFloat: {
+        const auto typname = GetTypeBasic(type.VectorType());
+        return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \
+               lifetime + ",  " + typname + ">>>";
+      }
+      case ftVectorOfBool: {
+        return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \
+               lifetime + ", bool>>>";
+      }
+      case ftVectorOfEnumKey: {
+        const auto typname = WrapInNameSpace(*type.enum_def);
+        return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \
+               lifetime + ", " + typname + ">>>";
+      }
+      case ftVectorOfStruct: {
+        const auto typname = WrapInNameSpace(*type.struct_def);
+        return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \
+               lifetime + ", " + typname + ">>>";
+      }
+      case ftVectorOfTable: {
+        const auto typname = WrapInNameSpace(*type.struct_def);
+        return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \
+               lifetime + ", flatbuffers::ForwardsUOffset<" + typname + \
+               "<" + lifetime + ">>>>>";
+      }
+      case ftVectorOfString: {
+        return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \
+               lifetime + ", flatbuffers::ForwardsUOffset<&" + lifetime + \
+               " str>>>>";
+      }
+      case ftVectorOfUnionValue: {
+        const auto typname = WrapInNameSpace(*type.enum_def) + \
+                             "UnionTableOffset";
+        return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \
+               lifetime + ", flatbuffers::ForwardsUOffset<"
+               "flatbuffers::Table<" + lifetime + ">>>>";
+      }
+    }
+    return "INVALID_CODE_GENERATION"; // for return analysis
+  }
+
+  std::string TableBuilderArgsDefaultValue(const FieldDef &field) {
+    return GetDefaultScalarValue(field);
+  }
+  std::string TableBuilderAddFuncDefaultValue(const FieldDef &field) {
+    // All branches of switch do the same action!
+    switch (GetFullType(field.value.type)) {
+      case ftUnionKey:
+      case ftEnumKey: {
+        const std::string basetype = GetTypeBasic(field.value.type); //<- never used
+        return GetDefaultScalarValue(field);
+      }
+
+      default: { return GetDefaultScalarValue(field); }
+    }
+  }
+
+  std::string TableBuilderArgsAddFuncType(const FieldDef &field,
+                                          const std::string &lifetime) {
+    const Type& type = field.value.type;
+
+    switch (GetFullType(field.value.type)) {
+      case ftVectorOfStruct: {
+        const auto typname = WrapInNameSpace(*type.struct_def);
+        return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \
+               ", " + typname + ">>";
+      }
+      case ftVectorOfTable: {
+        const auto typname = WrapInNameSpace(*type.struct_def);
+        return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \
+               ", flatbuffers::ForwardsUOffset<" + typname + \
+               "<" + lifetime + ">>>>";
+      }
+      case ftVectorOfInteger:
+      case ftVectorOfFloat: {
+        const auto typname = GetTypeBasic(type.VectorType());
+        return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \
+               ", " + typname + ">>";
+      }
+      case ftVectorOfBool: {
+        return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \
+               ", bool>>";
+      }
+      case ftVectorOfString: {
+        return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \
+               ", flatbuffers::ForwardsUOffset<&" + lifetime + " str>>>";
+      }
+      case ftVectorOfEnumKey: {
+        const auto typname = WrapInNameSpace(*type.enum_def);
+        return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \
+               ", " + typname + ">>";
+      }
+      case ftVectorOfUnionValue: {
+        return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \
+               ", flatbuffers::ForwardsUOffset<flatbuffers::Table<" + \
+               lifetime + ">>>";
+      }
+      case ftEnumKey: {
+        const auto typname = WrapInNameSpace(*type.enum_def);
+        return typname;
+      }
+      case ftStruct: {
+        const auto typname = WrapInNameSpace(*type.struct_def);
+        return "&" + lifetime + " " + typname + "";
+      }
+      case ftTable: {
+        const auto typname = WrapInNameSpace(*type.struct_def);
+        return "flatbuffers::WIPOffset<" + typname + "<" + lifetime + ">>";
+      }
+      case ftInteger:
+      case ftFloat: {
+        const auto typname = GetTypeBasic(type);
+        return typname;
+      }
+      case ftBool: {
+        return "bool";
+      }
+      case ftString: {
+        return "flatbuffers::WIPOffset<&" + lifetime + " str>";
+      }
+      case ftUnionKey: {
+        const auto typname = WrapInNameSpace(*type.enum_def);
+        return typname;
+      }
+      case ftUnionValue: {
+        return "flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>";
+      }
+    }
+
+    return "INVALID_CODE_GENERATION"; // for return analysis
+  }
+
+  std::string TableBuilderArgsAddFuncBody(const FieldDef &field) {
+    const Type& type = field.value.type;
+
+    switch (GetFullType(field.value.type)) {
+      case ftInteger:
+      case ftFloat: {
+        const auto typname = GetTypeBasic(field.value.type);
+        return "self.fbb_.push_slot::<" + typname + ">";
+      }
+      case ftBool: {
+        return "self.fbb_.push_slot::<bool>";
+      }
+
+      case ftEnumKey:
+      case ftUnionKey: {
+        const auto underlying_typname = GetTypeBasic(type);
+        return "self.fbb_.push_slot::<" + underlying_typname + ">";
+      }
+
+      case ftStruct: {
+        const std::string typname = WrapInNameSpace(*type.struct_def);
+        return "self.fbb_.push_slot_always::<&" + typname + ">";
+      }
+      case ftTable: {
+        const auto typname = WrapInNameSpace(*type.struct_def);
+        return "self.fbb_.push_slot_always::<flatbuffers::WIPOffset<" + \
+               typname +  ">>";
+      }
+
+      case ftUnionValue:
+      case ftString:
+      case ftVectorOfInteger:
+      case ftVectorOfFloat:
+      case ftVectorOfBool:
+      case ftVectorOfEnumKey:
+      case ftVectorOfStruct:
+      case ftVectorOfTable:
+      case ftVectorOfString:
+      case ftVectorOfUnionValue: {
+        return "self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>";
+      }
+    }
+    return "INVALID_CODE_GENERATION"; // for return analysis
+  }
+
+  std::string GenTableAccessorFuncReturnType(const FieldDef &field,
+                                             const std::string &lifetime) {
+    const Type& type = field.value.type;
+
+    switch (GetFullType(field.value.type)) {
+      case ftInteger:
+      case ftFloat: {
+        const auto typname = GetTypeBasic(type);
+        return typname;
+      }
+      case ftBool: {
+        return "bool";
+      }
+      case ftStruct: {
+        const auto typname = WrapInNameSpace(*type.struct_def);
+        return WrapInOptionIfNotRequired("&" + lifetime + " " + typname, field.required);
+      }
+      case ftTable: {
+        const auto typname = WrapInNameSpace(*type.struct_def);
+        return WrapInOptionIfNotRequired(typname + "<" + lifetime + ">", field.required);
+      }
+      case ftEnumKey:
+      case ftUnionKey: {
+        const auto typname = WrapInNameSpace(*type.enum_def);
+        return typname;
+      }
+
+      case ftUnionValue: {
+        return WrapInOptionIfNotRequired("flatbuffers::Table<" + lifetime + ">", field.required);
+      }
+      case ftString: {
+         return WrapInOptionIfNotRequired("&" + lifetime + " str", field.required);
+      }
+      case ftVectorOfInteger:
+      case ftVectorOfFloat: {
+        const auto typname = GetTypeBasic(type.VectorType());
+        if (IsOneByte(type.VectorType().base_type)) {
+          return WrapInOptionIfNotRequired("&" + lifetime + " [" + typname + "]", field.required);
+        }
+        return WrapInOptionIfNotRequired("flatbuffers::Vector<" + lifetime + ", " + typname + ">", field.required);
+      }
+      case ftVectorOfBool: {
+        return WrapInOptionIfNotRequired("&" + lifetime + " [bool]", field.required);
+      }
+      case ftVectorOfEnumKey: {
+        const auto typname = WrapInNameSpace(*type.enum_def);
+        return WrapInOptionIfNotRequired("flatbuffers::Vector<" + lifetime + ", " + typname + ">", field.required);
+      }
+      case ftVectorOfStruct: {
+        const auto typname = WrapInNameSpace(*type.struct_def);
+        return WrapInOptionIfNotRequired("&" + lifetime + " [" + typname + "]", field.required);
+      }
+      case ftVectorOfTable: {
+        const auto typname = WrapInNameSpace(*type.struct_def);
+        return WrapInOptionIfNotRequired("flatbuffers::Vector<" + lifetime + ", flatbuffers::ForwardsUOffset<" + \
+               typname + "<" + lifetime + ">>>", field.required);
+      }
+      case ftVectorOfString: {
+        return WrapInOptionIfNotRequired("flatbuffers::Vector<" + lifetime + ", flatbuffers::ForwardsUOffset<&" + \
+               lifetime + " str>>", field.required);
+      }
+      case ftVectorOfUnionValue: {
+        FLATBUFFERS_ASSERT(false && "vectors of unions are not yet supported");
+        // TODO(rw): when we do support these, we should consider using the
+        //           Into trait to convert tables to typesafe union values.
+        return "INVALID_CODE_GENERATION"; // for return analysis
+      }
+    }
+    return "INVALID_CODE_GENERATION"; // for return analysis
+  }
+
+  std::string GenTableAccessorFuncBody(const FieldDef &field,
+                                       const std::string &lifetime,
+                                       const std::string &offset_prefix) {
+    const std::string offset_name = offset_prefix + "::" + \
+                                    GetFieldOffsetName(field);
+    const Type& type = field.value.type;
+
+    switch (GetFullType(field.value.type)) {
+      case ftInteger:
+      case ftFloat:
+      case ftBool: {
+        const auto typname = GetTypeBasic(type);
+        const auto default_value = GetDefaultScalarValue(field);
+        return "self._tab.get::<" + typname + ">(" + offset_name + ", Some(" + \
+               default_value + ")).unwrap()";
+      }
+      case ftStruct: {
+        const auto typname = WrapInNameSpace(*type.struct_def);
+        return AddUnwrapIfRequired("self._tab.get::<" + typname + ">(" + offset_name + ", None)", field.required);
+      }
+      case ftTable: {
+        const auto typname = WrapInNameSpace(*type.struct_def);
+        return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<" + \
+               typname + "<" + lifetime + ">>>(" + offset_name + ", None)", field.required);
+      }
+      case ftUnionValue: {
+        return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<"
+               "flatbuffers::Table<" + lifetime + ">>>(" + offset_name + \
+               ", None)", field.required);
+      }
+      case ftUnionKey:
+      case ftEnumKey: {
+        const auto underlying_typname = GetTypeBasic(type); //<- never used
+        const auto typname = WrapInNameSpace(*type.enum_def);
+        const auto default_value = GetDefaultScalarValue(field);
+        return "self._tab.get::<" + typname + ">(" + offset_name + \
+               ", Some(" + default_value + ")).unwrap()";
+      }
+      case ftString: {
+        return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(" + \
+               offset_name + ", None)", field.required);
+      }
+
+      case ftVectorOfInteger:
+      case ftVectorOfFloat: {
+        const auto typname = GetTypeBasic(type.VectorType());
+        std::string s = "self._tab.get::<flatbuffers::ForwardsUOffset<"
+                        "flatbuffers::Vector<" + lifetime + ", " + typname + \
+                        ">>>(" + offset_name + ", None)";
+        // single-byte values are safe to slice
+        if (IsOneByte(type.VectorType().base_type)) {
+          s += ".map(|v| v.safe_slice())";
+        }
+        return AddUnwrapIfRequired(s, field.required);
+      }
+      case ftVectorOfBool: {
+        return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<"
+               "flatbuffers::Vector<" + lifetime + ", bool>>>(" + \
+               offset_name + ", None).map(|v| v.safe_slice())", field.required);
+      }
+      case ftVectorOfEnumKey: {
+        const auto typname = WrapInNameSpace(*type.enum_def);
+        return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<"
+               "flatbuffers::Vector<" + lifetime + ", " + typname + ">>>(" + \
+               offset_name + ", None)", field.required);
+      }
+      case ftVectorOfStruct: {
+        const auto typname = WrapInNameSpace(*type.struct_def);
+        return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<"
+               "flatbuffers::Vector<" + typname + ">>>(" + \
+               offset_name + ", None).map(|v| v.safe_slice() )", field.required);
+      }
+      case ftVectorOfTable: {
+        const auto typname = WrapInNameSpace(*type.struct_def);
+        return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<"
+               "flatbuffers::Vector<flatbuffers::ForwardsUOffset<" + typname + \
+               "<" + lifetime + ">>>>>(" + offset_name + ", None)", field.required);
+      }
+      case ftVectorOfString: {
+        return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<"
+               "flatbuffers::Vector<flatbuffers::ForwardsUOffset<&" + \
+               lifetime + " str>>>>(" + offset_name + ", None)", field.required);
+      }
+      case ftVectorOfUnionValue: {
+        FLATBUFFERS_ASSERT(false && "vectors of unions are not yet supported");
+        return "INVALID_CODE_GENERATION"; // for return analysis
+      }
+    }
+    return "INVALID_CODE_GENERATION"; // for return analysis
+  }
+
+  bool TableFieldReturnsOption(const Type& type) {
+    switch (GetFullType(type)) {
+      case ftInteger:
+      case ftFloat:
+      case ftBool:
+      case ftEnumKey:
+      case ftUnionKey:
+        return false;
+      default: return true;
+    }
+  }
+
+  // Generate an accessor struct, builder struct, and create function for a
+  // table.
+  void GenTable(const StructDef &struct_def) {
+    code_.SetValue("STRUCT_NAME", Name(struct_def));
+    code_.SetValue("OFFSET_TYPELABEL", Name(struct_def) + "Offset");
+    code_.SetValue("STRUCT_NAME_SNAKECASE", MakeSnakeCase(Name(struct_def)));
+
+    // Generate an offset type, the base type, the Follow impl, and the
+    // init_from_table impl.
+    code_ += "pub enum {{OFFSET_TYPELABEL}} {}";
+    code_ += "#[derive(Copy, Clone, Debug, PartialEq)]";
+    code_ += "";
+
+    GenComment(struct_def.doc_comment);
+
+    code_ += "pub struct {{STRUCT_NAME}}<'a> {";
+    code_ += "  pub _tab: flatbuffers::Table<'a>,";
+    code_ += "}";
+    code_ += "";
+    code_ += "impl<'a> flatbuffers::Follow<'a> for {{STRUCT_NAME}}<'a> {";
+    code_ += "    type Inner = {{STRUCT_NAME}}<'a>;";
+    code_ += "    #[inline]";
+    code_ += "    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {";
+    code_ += "        Self {";
+    code_ += "            _tab: flatbuffers::Table { buf: buf, loc: loc },";
+    code_ += "        }";
+    code_ += "    }";
+    code_ += "}";
+    code_ += "";
+    code_ += "impl<'a> {{STRUCT_NAME}}<'a> {";
+    code_ += "    #[inline]";
+    code_ += "    pub fn init_from_table(table: flatbuffers::Table<'a>) -> "
+             "Self {";
+    code_ += "        {{STRUCT_NAME}} {";
+    code_ += "            _tab: table,";
+    code_ += "        }";
+    code_ += "    }";
+
+    // Generate a convenient create* function that uses the above builder
+    // to create a table in one function call.
+    code_.SetValue("MAYBE_US",
+        struct_def.fields.vec.size() == 0 ? "_" : "");
+    code_.SetValue("MAYBE_LT",
+        TableBuilderArgsNeedsLifetime(struct_def) ? "<'args>" : "");
+    code_ += "    #[allow(unused_mut)]";
+    code_ += "    pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(";
+    code_ += "        _fbb: "
+             "&'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,";
+    code_ += "        {{MAYBE_US}}args: &'args {{STRUCT_NAME}}Args{{MAYBE_LT}})"
+             " -> flatbuffers::WIPOffset<{{STRUCT_NAME}}<'bldr>> {";
+
+    code_ += "      let mut builder = {{STRUCT_NAME}}Builder::new(_fbb);";
+    for (size_t size = struct_def.sortbysize ? sizeof(largest_scalar_t) : 1;
+         size; size /= 2) {
+      for (auto it = struct_def.fields.vec.rbegin();
+           it != struct_def.fields.vec.rend(); ++it) {
+        const auto &field = **it;
+        // TODO(rw): fully understand this sortbysize usage
+        if (!field.deprecated && (!struct_def.sortbysize ||
+                                  size == SizeOf(field.value.type.base_type))) {
+          code_.SetValue("FIELD_NAME", Name(field));
+          if (TableFieldReturnsOption(field.value.type)) {
+            code_ += "      if let Some(x) = args.{{FIELD_NAME}} "
+                     "{ builder.add_{{FIELD_NAME}}(x); }";
+          } else {
+            code_ += "      builder.add_{{FIELD_NAME}}(args.{{FIELD_NAME}});";
+          }
+        }
+      }
+    }
+    code_ += "      builder.finish()";
+    code_ += "    }";
+    code_ += "";
+
+    // Generate field id constants.
+    if (struct_def.fields.vec.size() > 0) {
+      for (auto it = struct_def.fields.vec.begin();
+           it != struct_def.fields.vec.end(); ++it) {
+        const auto &field = **it;
+        if (field.deprecated) {
+          // Deprecated fields won't be accessible.
+          continue;
+        }
+
+        code_.SetValue("OFFSET_NAME", GetFieldOffsetName(field));
+        code_.SetValue("OFFSET_VALUE", NumToString(field.value.offset));
+        code_ += "    pub const {{OFFSET_NAME}}: flatbuffers::VOffsetT = "
+                 "{{OFFSET_VALUE}};";
+      }
+      code_ += "";
+    }
+
+    // Generate the accessors. Each has one of two forms:
+    //
+    // If a value can be None:
+    //   pub fn name(&'a self) -> Option<user_facing_type> {
+    //     self._tab.get::<internal_type>(offset, defaultval)
+    //   }
+    //
+    // If a value is always Some:
+    //   pub fn name(&'a self) -> user_facing_type {
+    //     self._tab.get::<internal_type>(offset, defaultval).unwrap()
+    //   }
+    const auto offset_prefix = Name(struct_def);
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+      if (field.deprecated) {
+        // Deprecated fields won't be accessible.
+        continue;
+      }
+
+      code_.SetValue("FIELD_NAME", Name(field));
+      code_.SetValue("RETURN_TYPE",
+                     GenTableAccessorFuncReturnType(field, "'a"));
+      code_.SetValue("FUNC_BODY",
+                     GenTableAccessorFuncBody(field, "'a", offset_prefix));
+
+      GenComment(field.doc_comment, "  ");
+      code_ += "  #[inline]";
+      code_ += "  pub fn {{FIELD_NAME}}(&self) -> {{RETURN_TYPE}} {";
+      code_ += "    {{FUNC_BODY}}";
+      code_ += "  }";
+
+      // Generate a comparison function for this field if it is a key.
+      if (field.key) {
+        GenKeyFieldMethods(field);
+      }
+
+      // Generate a nested flatbuffer field, if applicable.
+      auto nested = field.attributes.Lookup("nested_flatbuffer");
+      if (nested) {
+        std::string qualified_name = nested->constant;
+        auto nested_root = parser_.LookupStruct(nested->constant);
+        if (nested_root == nullptr) {
+          qualified_name = parser_.current_namespace_->GetFullyQualifiedName(
+              nested->constant);
+          nested_root = parser_.LookupStruct(qualified_name);
+        }
+        FLATBUFFERS_ASSERT(nested_root);  // Guaranteed to exist by parser.
+        (void)nested_root;
+
+        code_.SetValue("OFFSET_NAME",
+                       offset_prefix + "::" + GetFieldOffsetName(field));
+        code_ += "  pub fn {{FIELD_NAME}}_nested_flatbuffer(&'a self) -> "
+                 " Option<{{STRUCT_NAME}}<'a>> {";
+        code_ += "     match self.{{FIELD_NAME}}() {";
+        code_ += "         None => { None }";
+        code_ += "         Some(data) => {";
+        code_ += "             use self::flatbuffers::Follow;";
+        code_ += "             Some(<flatbuffers::ForwardsUOffset"
+                 "<{{STRUCT_NAME}}<'a>>>::follow(data, 0))";
+        code_ += "         },";
+        code_ += "     }";
+        code_ += "  }";
+      }
+    }
+
+    // Explicit specializations for union accessors
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+      if (field.deprecated || field.value.type.base_type != BASE_TYPE_UNION) {
+        continue;
+      }
+
+      auto u = field.value.type.enum_def;
+
+      code_.SetValue("FIELD_NAME", Name(field));
+
+      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 table_init_type = WrapInNameSpace(
+          ev.union_type.struct_def->defined_namespace,
+          ev.union_type.struct_def->name);
+
+          code_.SetValue("U_ELEMENT_ENUM_TYPE",
+              WrapInNameSpace(u->defined_namespace, GetEnumValUse(*u, ev)));
+        code_.SetValue("U_ELEMENT_TABLE_TYPE", table_init_type);
+        code_.SetValue("U_ELEMENT_NAME", MakeSnakeCase(Name(ev)));
+
+        code_ += "  #[inline]";
+        code_ += "  #[allow(non_snake_case)]";
+        code_ += "  pub fn {{FIELD_NAME}}_as_{{U_ELEMENT_NAME}}(&self) -> "
+                 "Option<{{U_ELEMENT_TABLE_TYPE}}<'a>> {";
+        code_ += "    if self.{{FIELD_NAME}}_type() == {{U_ELEMENT_ENUM_TYPE}} {";
+        code_ += "      self.{{FIELD_NAME}}().map(|u| "
+                 "{{U_ELEMENT_TABLE_TYPE}}::init_from_table(u))";
+        code_ += "    } else {";
+        code_ += "      None";
+        code_ += "    }";
+        code_ += "  }";
+        code_ += "";
+      }
+    }
+
+    code_ += "}";  // End of table impl.
+    code_ += "";
+
+    // Generate an args struct:
+    code_.SetValue("MAYBE_LT",
+        TableBuilderArgsNeedsLifetime(struct_def) ? "<'a>" : "");
+    code_ += "pub struct {{STRUCT_NAME}}Args{{MAYBE_LT}} {";
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+      if (!field.deprecated) {
+        code_.SetValue("PARAM_NAME", Name(field));
+        code_.SetValue("PARAM_TYPE", TableBuilderArgsDefnType(field, "'a "));
+        code_ += "    pub {{PARAM_NAME}}: {{PARAM_TYPE}},";
+      }
+    }
+    code_ += "}";
+
+    // Generate an impl of Default for the *Args type:
+    code_ += "impl<'a> Default for {{STRUCT_NAME}}Args{{MAYBE_LT}} {";
+    code_ += "    #[inline]";
+    code_ += "    fn default() -> Self {";
+    code_ += "        {{STRUCT_NAME}}Args {";
+    for (auto it = struct_def.fields.vec.begin();
+        it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+      if (!field.deprecated) {
+        code_.SetValue("PARAM_VALUE", TableBuilderArgsDefaultValue(field));
+        code_.SetValue("REQ", field.required ? " // required field" : "");
+        code_.SetValue("PARAM_NAME", Name(field));
+        code_ += "            {{PARAM_NAME}}: {{PARAM_VALUE}},{{REQ}}";
+      }
+    }
+    code_ += "        }";
+    code_ += "    }";
+    code_ += "}";
+
+    // Generate a builder struct:
+    code_ += "pub struct {{STRUCT_NAME}}Builder<'a: 'b, 'b> {";
+    code_ += "  fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,";
+    code_ += "  start_: flatbuffers::WIPOffset<"
+             "flatbuffers::TableUnfinishedWIPOffset>,";
+    code_ += "}";
+
+    // Generate builder functions:
+    code_ += "impl<'a: 'b, 'b> {{STRUCT_NAME}}Builder<'a, 'b> {";
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+      if (!field.deprecated) {
+        const bool is_scalar = IsScalar(field.value.type.base_type);
+
+        std::string offset = GetFieldOffsetName(field);
+
+        // Generate functions to add data, which take one of two forms.
+        //
+        // If a value has a default:
+        //   fn add_x(x_: type) {
+        //     fbb_.push_slot::<type>(offset, x_, Some(default));
+        //   }
+        //
+        // If a value does not have a default:
+        //   fn add_x(x_: type) {
+        //     fbb_.push_slot_always::<type>(offset, x_);
+        //   }
+        code_.SetValue("FIELD_NAME", Name(field));
+        code_.SetValue("FIELD_OFFSET", Name(struct_def) + "::" + offset);
+        code_.SetValue("FIELD_TYPE", TableBuilderArgsAddFuncType(field, "'b "));
+        code_.SetValue("FUNC_BODY", TableBuilderArgsAddFuncBody(field));
+        code_ += "  #[inline]";
+        code_ += "  pub fn add_{{FIELD_NAME}}(&mut self, {{FIELD_NAME}}: "
+                 "{{FIELD_TYPE}}) {";
+        if (is_scalar) {
+          code_.SetValue("FIELD_DEFAULT_VALUE",
+                         TableBuilderAddFuncDefaultValue(field));
+          code_ += "    {{FUNC_BODY}}({{FIELD_OFFSET}}, {{FIELD_NAME}}, "
+                   "{{FIELD_DEFAULT_VALUE}});";
+        } else {
+          code_ += "    {{FUNC_BODY}}({{FIELD_OFFSET}}, {{FIELD_NAME}});";
+        }
+        code_ += "  }";
+      }
+    }
+
+    // Struct initializer (all fields required);
+    code_ += "  #[inline]";
+    code_ +=
+        "  pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> "
+        "{{STRUCT_NAME}}Builder<'a, 'b> {";
+    code_.SetValue("NUM_FIELDS", NumToString(struct_def.fields.vec.size()));
+    code_ += "    let start = _fbb.start_table();";
+    code_ += "    {{STRUCT_NAME}}Builder {";
+    code_ += "      fbb_: _fbb,";
+    code_ += "      start_: start,";
+    code_ += "    }";
+    code_ += "  }";
+
+    // finish() function.
+    code_ += "  #[inline]";
+    code_ += "  pub fn finish(self) -> "
+             "flatbuffers::WIPOffset<{{STRUCT_NAME}}<'a>> {";
+    code_ += "    let o = self.fbb_.end_table(self.start_);";
+
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+      if (!field.deprecated && field.required) {
+        code_.SetValue("FIELD_NAME", MakeSnakeCase(Name(field)));
+        code_.SetValue("OFFSET_NAME", GetFieldOffsetName(field));
+        code_ += "    self.fbb_.required(o, {{STRUCT_NAME}}::{{OFFSET_NAME}},"
+                 "\"{{FIELD_NAME}}\");";
+      }
+    }
+    code_ += "    flatbuffers::WIPOffset::new(o.value())";
+    code_ += "  }";
+    code_ += "}";
+    code_ += "";
+  }
+
+  // Generate functions to compare tables and structs by key. This function
+  // must only be called if the field key is defined.
+  void GenKeyFieldMethods(const FieldDef &field) {
+    FLATBUFFERS_ASSERT(field.key);
+
+    code_.SetValue("KEY_TYPE", GenTableAccessorFuncReturnType(field, ""));
+
+    code_ += "  #[inline]";
+    code_ += "  pub fn key_compare_less_than(&self, o: &{{STRUCT_NAME}}) -> "
+             " bool {";
+    code_ += "    self.{{FIELD_NAME}}() < o.{{FIELD_NAME}}()";
+    code_ += "  }";
+    code_ += "";
+    code_ += "  #[inline]";
+    code_ += "  pub fn key_compare_with_value(&self, val: {{KEY_TYPE}}) -> "
+             " ::std::cmp::Ordering {";
+    code_ += "    let key = self.{{FIELD_NAME}}();";
+    code_ += "    key.cmp(&val)";
+    code_ += "  }";
+  }
+
+  // Generate functions for accessing the root table object. This function
+  // must only be called if the root table is defined.
+  void GenRootTableFuncs(const StructDef &struct_def) {
+    FLATBUFFERS_ASSERT(parser_.root_struct_def_ && "root table not defined");
+    auto name = Name(struct_def);
+
+    code_.SetValue("STRUCT_NAME", name);
+    code_.SetValue("STRUCT_NAME_SNAKECASE", MakeSnakeCase(name));
+    code_.SetValue("STRUCT_NAME_CAPS", MakeUpper(MakeSnakeCase(name)));
+
+    // The root datatype accessors:
+    code_ += "#[inline]";
+    code_ +=
+        "pub fn get_root_as_{{STRUCT_NAME_SNAKECASE}}<'a>(buf: &'a [u8])"
+        " -> {{STRUCT_NAME}}<'a> {";
+    code_ += "  flatbuffers::get_root::<{{STRUCT_NAME}}<'a>>(buf)";
+    code_ += "}";
+    code_ += "";
+
+    code_ += "#[inline]";
+    code_ += "pub fn get_size_prefixed_root_as_{{STRUCT_NAME_SNAKECASE}}"
+             "<'a>(buf: &'a [u8]) -> {{STRUCT_NAME}}<'a> {";
+    code_ += "  flatbuffers::get_size_prefixed_root::<{{STRUCT_NAME}}<'a>>"
+             "(buf)";
+    code_ += "}";
+    code_ += "";
+
+    if (parser_.file_identifier_.length()) {
+      // Declare the identifier
+      code_ += "pub const {{STRUCT_NAME_CAPS}}_IDENTIFIER: &'static str\\";
+      code_ += " = \"" + parser_.file_identifier_ + "\";";
+      code_ += "";
+
+      // Check if a buffer has the identifier.
+      code_ += "#[inline]";
+      code_ += "pub fn {{STRUCT_NAME_SNAKECASE}}_buffer_has_identifier\\";
+      code_ += "(buf: &[u8]) -> bool {";
+      code_ += "  return flatbuffers::buffer_has_identifier(buf, \\";
+      code_ += "{{STRUCT_NAME_CAPS}}_IDENTIFIER, false);";
+      code_ += "}";
+      code_ += "";
+      code_ += "#[inline]";
+      code_ += "pub fn {{STRUCT_NAME_SNAKECASE}}_size_prefixed\\";
+      code_ += "_buffer_has_identifier(buf: &[u8]) -> bool {";
+      code_ += "  return flatbuffers::buffer_has_identifier(buf, \\";
+      code_ += "{{STRUCT_NAME_CAPS}}_IDENTIFIER, true);";
+      code_ += "}";
+      code_ += "";
+    }
+
+    if (parser_.file_extension_.length()) {
+      // Return the extension
+      code_ += "pub const {{STRUCT_NAME_CAPS}}_EXTENSION: &'static str = \\";
+      code_ += "\"" + parser_.file_extension_ + "\";";
+      code_ += "";
+    }
+
+    // Finish a buffer with a given root object:
+    code_.SetValue("OFFSET_TYPELABEL", Name(struct_def) + "Offset");
+    code_ += "#[inline]";
+    code_ += "pub fn finish_{{STRUCT_NAME_SNAKECASE}}_buffer<'a, 'b>(";
+    code_ += "    fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>,";
+    code_ += "    root: flatbuffers::WIPOffset<{{STRUCT_NAME}}<'a>>) {";
+    if (parser_.file_identifier_.length()) {
+      code_ += "  fbb.finish(root, Some({{STRUCT_NAME_CAPS}}_IDENTIFIER));";
+    } else {
+      code_ += "  fbb.finish(root, None);";
+    }
+    code_ += "}";
+    code_ += "";
+    code_ += "#[inline]";
+    code_ += "pub fn finish_size_prefixed_{{STRUCT_NAME_SNAKECASE}}_buffer"
+             "<'a, 'b>("
+             "fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, "
+             "root: flatbuffers::WIPOffset<{{STRUCT_NAME}}<'a>>) {";
+    if (parser_.file_identifier_.length()) {
+      code_ += "  fbb.finish_size_prefixed(root, "
+               "Some({{STRUCT_NAME_CAPS}}_IDENTIFIER));";
+    } else {
+      code_ += "  fbb.finish_size_prefixed(root, None);";
+    }
+    code_ += "}";
+  }
+
+  static void GenPadding(
+      const FieldDef &field, std::string *code_ptr, int *id,
+      const std::function<void(int bits, std::string *code_ptr, int *id)> &f) {
+    if (field.padding) {
+      for (int i = 0; i < 4; i++) {
+        if (static_cast<int>(field.padding) & (1 << i)) {
+          f((1 << i) * 8, code_ptr, id);
+        }
+      }
+      assert(!(field.padding & ~0xF));
+    }
+  }
+
+  static void PaddingDefinition(int bits, std::string *code_ptr, int *id) {
+    *code_ptr += "  padding" + NumToString((*id)++) + "__: u" + \
+                 NumToString(bits) + ",";
+  }
+
+  static void PaddingInitializer(int bits, std::string *code_ptr, int *id) {
+    (void)bits;
+    *code_ptr += "padding" + NumToString((*id)++) + "__: 0,";
+  }
+
+  // Generate an accessor struct with constructor for a flatbuffers struct.
+  void GenStruct(const StructDef &struct_def) {
+    // Generates manual padding and alignment.
+    // Variables are private because they contain little endian data on all
+    // platforms.
+    GenComment(struct_def.doc_comment);
+    code_.SetValue("ALIGN", NumToString(struct_def.minalign));
+    code_.SetValue("STRUCT_NAME", Name(struct_def));
+
+    code_ += "// struct {{STRUCT_NAME}}, aligned to {{ALIGN}}";
+    code_ += "#[repr(C, align({{ALIGN}}))]";
+
+    // PartialEq is useful to derive because we can correctly compare structs
+    // for equality by just comparing their underlying byte data. This doesn't
+    // hold for PartialOrd/Ord.
+    code_ += "#[derive(Clone, Copy, Debug, PartialEq)]";
+    code_ += "pub struct {{STRUCT_NAME}} {";
+
+    int padding_id = 0;
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+      code_.SetValue("FIELD_TYPE", GetTypeGet(field.value.type));
+      code_.SetValue("FIELD_NAME", Name(field));
+      code_ += "  {{FIELD_NAME}}_: {{FIELD_TYPE}},";
+
+      if (field.padding) {
+        std::string padding;
+        GenPadding(field, &padding, &padding_id, PaddingDefinition);
+        code_ += padding;
+      }
+    }
+
+    code_ += "} // pub struct {{STRUCT_NAME}}";
+
+    // Generate impls for SafeSliceAccess (because all structs are endian-safe),
+    // Follow for the value type, Follow for the reference type, Push for the
+    // value type, and Push for the reference type.
+    code_ += "impl flatbuffers::SafeSliceAccess for {{STRUCT_NAME}} {}";
+    code_ += "impl<'a> flatbuffers::Follow<'a> for {{STRUCT_NAME}} {";
+    code_ += "  type Inner = &'a {{STRUCT_NAME}};";
+    code_ += "  #[inline]";
+    code_ += "  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {";
+    code_ += "    <&'a {{STRUCT_NAME}}>::follow(buf, loc)";
+    code_ += "  }";
+    code_ += "}";
+    code_ += "impl<'a> flatbuffers::Follow<'a> for &'a {{STRUCT_NAME}} {";
+    code_ += "  type Inner = &'a {{STRUCT_NAME}};";
+    code_ += "  #[inline]";
+    code_ += "  fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {";
+    code_ += "    flatbuffers::follow_cast_ref::<{{STRUCT_NAME}}>(buf, loc)";
+    code_ += "  }";
+    code_ += "}";
+    code_ += "impl<'b> flatbuffers::Push for {{STRUCT_NAME}} {";
+    code_ += "    type Output = {{STRUCT_NAME}};";
+    code_ += "    #[inline]";
+    code_ += "    fn push(&self, dst: &mut [u8], _rest: &[u8]) {";
+    code_ += "        let src = unsafe {";
+    code_ += "            ::std::slice::from_raw_parts("
+             "self as *const {{STRUCT_NAME}} as *const u8, Self::size())";
+    code_ += "        };";
+    code_ += "        dst.copy_from_slice(src);";
+    code_ += "    }";
+    code_ += "}";
+    code_ += "impl<'b> flatbuffers::Push for &'b {{STRUCT_NAME}} {";
+    code_ += "    type Output = {{STRUCT_NAME}};";
+    code_ += "";
+    code_ += "    #[inline]";
+    code_ += "    fn push(&self, dst: &mut [u8], _rest: &[u8]) {";
+    code_ += "        let src = unsafe {";
+    code_ += "            ::std::slice::from_raw_parts("
+             "*self as *const {{STRUCT_NAME}} as *const u8, Self::size())";
+    code_ += "        };";
+    code_ += "        dst.copy_from_slice(src);";
+    code_ += "    }";
+    code_ += "}";
+    code_ += "";
+    code_ += "";
+
+    // Generate a constructor that takes all fields as arguments.
+    code_ += "impl {{STRUCT_NAME}} {";
+    std::string arg_list;
+    std::string init_list;
+    padding_id = 0;
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+      const auto member_name = Name(field) + "_";
+      const auto reference = StructMemberAccessNeedsCopy(field.value.type)
+                             ? "" : "&'a ";
+      const auto arg_name = "_" + Name(field);
+      const auto arg_type = reference + GetTypeGet(field.value.type);
+
+      if (it != struct_def.fields.vec.begin()) {
+        arg_list += ", ";
+      }
+      arg_list += arg_name + ": ";
+      arg_list += arg_type;
+      init_list += "      " + member_name;
+      if (StructMemberAccessNeedsCopy(field.value.type)) {
+        init_list += ": " + arg_name + ".to_little_endian(),\n";
+      } else {
+        init_list += ": *" + arg_name + ",\n";
+      }
+    }
+
+    code_.SetValue("ARG_LIST", arg_list);
+    code_.SetValue("INIT_LIST", init_list);
+    code_ += "  pub fn new<'a>({{ARG_LIST}}) -> Self {";
+    code_ += "    {{STRUCT_NAME}} {";
+    code_ += "{{INIT_LIST}}";
+    padding_id = 0;
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+      if (field.padding) {
+        std::string padding;
+        GenPadding(field, &padding, &padding_id, PaddingInitializer);
+        code_ += "      " + padding;
+      }
+    }
+    code_ += "    }";
+    code_ += "  }";
+
+    // Generate accessor methods for the struct.
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      const auto &field = **it;
+
+      auto field_type = TableBuilderArgsAddFuncType(field, "'a");
+      auto member = "self." + Name(field) + "_";
+      auto value = StructMemberAccessNeedsCopy(field.value.type) ?
+        member + ".from_little_endian()" : member;
+
+      code_.SetValue("FIELD_NAME", Name(field));
+      code_.SetValue("FIELD_TYPE", field_type);
+      code_.SetValue("FIELD_VALUE", value);
+      code_.SetValue("REF", IsStruct(field.value.type) ? "&" : "");
+
+      GenComment(field.doc_comment, "  ");
+      code_ += "  pub fn {{FIELD_NAME}}<'a>(&'a self) -> {{FIELD_TYPE}} {";
+      code_ += "    {{REF}}{{FIELD_VALUE}}";
+      code_ += "  }";
+
+      // Generate a comparison function for this field if it is a key.
+      if (field.key) {
+        GenKeyFieldMethods(field);
+      }
+    }
+    code_ += "}";
+    code_ += "";
+  }
+
+  void GenNamespaceImports(const int white_spaces) {
+      std::string indent = std::string(white_spaces, ' ');
+      code_ += "";
+      code_ += indent + "use std::mem;";
+      code_ += indent + "use std::cmp::Ordering;";
+      code_ += "";
+      code_ += indent + "extern crate flatbuffers;";
+      code_ += indent + "use self::flatbuffers::EndianScalar;";
+  }
+
+  // Set up the correct namespace. This opens a namespace if the current
+  // namespace is different from the target namespace. This function
+  // closes and opens the namespaces only as necessary.
+  //
+  // The file must start and end with an empty (or null) namespace so that
+  // namespaces are properly opened and closed.
+  void SetNameSpace(const Namespace *ns) {
+    if (cur_name_space_ == ns) { return; }
+
+    // Compute the size of the longest common namespace prefix.
+    // If cur_name_space is A::B::C::D and ns is A::B::E::F::G,
+    // the common prefix is A::B:: and we have old_size = 4, new_size = 5
+    // and common_prefix_size = 2
+    size_t old_size = cur_name_space_ ? cur_name_space_->components.size() : 0;
+    size_t new_size = ns ? ns->components.size() : 0;
+
+    size_t common_prefix_size = 0;
+    while (common_prefix_size < old_size && common_prefix_size < new_size &&
+           ns->components[common_prefix_size] ==
+               cur_name_space_->components[common_prefix_size]) {
+      common_prefix_size++;
+    }
+
+    // Close cur_name_space in reverse order to reach the common prefix.
+    // In the previous example, D then C are closed.
+    for (size_t j = old_size; j > common_prefix_size; --j) {
+      code_ += "}  // pub mod " + cur_name_space_->components[j - 1];
+    }
+    if (old_size != common_prefix_size) { code_ += ""; }
+
+    // open namespace parts to reach the ns namespace
+    // in the previous example, E, then F, then G are opened
+    for (auto j = common_prefix_size; j != new_size; ++j) {
+      code_ += "#[allow(unused_imports, dead_code)]";
+      code_ += "pub mod " + MakeSnakeCase(ns->components[j]) + " {";
+      // Generate local namespace imports.
+      GenNamespaceImports(2);
+    }
+    if (new_size != common_prefix_size) { code_ += ""; }
+
+    cur_name_space_ = ns;
+  }
+};
+
+}  // namespace rust
+
+bool GenerateRust(const Parser &parser, const std::string &path,
+                  const std::string &file_name) {
+  rust::RustGenerator generator(parser, path, file_name);
+  return generator.generate();
+}
+
+std::string RustMakeRule(const Parser &parser, const std::string &path,
+                         const std::string &file_name) {
+  std::string filebase =
+      flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
+  std::string make_rule = GeneratedFileName(path, filebase) + ": ";
+
+  auto included_files = parser.GetIncludedFilesRecursive(file_name);
+  for (auto it = included_files.begin(); it != included_files.end(); ++it) {
+    make_rule += " " + *it;
+  }
+  return make_rule;
+}
+
+}  // namespace flatbuffers
+
+// TODO(rw): Generated code should import other generated files.
+// TODO(rw): Generated code should refer to namespaces in included files in a
+//           way that makes them referrable.
+// TODO(rw): Generated code should indent according to nesting level.
+// TODO(rw): Generated code should generate endian-safe Debug impls.
+// TODO(rw): Generated code could use a Rust-only enum type to access unions,
+//           instead of making the user use _type() to manually switch.
diff --git a/src/idl_gen_text.cpp b/src/idl_gen_text.cpp
new file mode 100644
index 0000000..9825dce
--- /dev/null
+++ b/src/idl_gen_text.cpp
@@ -0,0 +1,378 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// independent from idl_parser, since this code is not needed for most clients
+
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/flexbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+namespace flatbuffers {
+
+static bool GenStruct(const StructDef &struct_def, const Table *table,
+                      int indent, const IDLOptions &opts, std::string *_text);
+
+// If indentation is less than 0, that indicates we don't want any newlines
+// either.
+const char *NewLine(const IDLOptions &opts) {
+  return opts.indent_step >= 0 ? "\n" : "";
+}
+
+int Indent(const IDLOptions &opts) { return std::max(opts.indent_step, 0); }
+
+// Output an identifier with or without quotes depending on strictness.
+void OutputIdentifier(const std::string &name, const IDLOptions &opts,
+                      std::string *_text) {
+  std::string &text = *_text;
+  if (opts.strict_json) text += "\"";
+  text += name;
+  if (opts.strict_json) text += "\"";
+}
+
+// Print (and its template specialization below for pointers) generate text
+// for a single FlatBuffer value into JSON format.
+// The general case for scalars:
+template<typename T>
+bool Print(T val, Type type, int /*indent*/, Type * /*union_type*/,
+           const IDLOptions &opts, std::string *_text) {
+  std::string &text = *_text;
+  if (type.enum_def && opts.output_enum_identifiers) {
+    std::vector<EnumVal const *> enum_values;
+    if (auto ev = type.enum_def->ReverseLookup(static_cast<int64_t>(val))) {
+      enum_values.push_back(ev);
+    } else if (val && type.enum_def->attributes.Lookup("bit_flags")) {
+      for (auto it = type.enum_def->Vals().begin(),
+                e = type.enum_def->Vals().end();
+           it != e; ++it) {
+        if ((*it)->GetAsUInt64() & static_cast<uint64_t>(val))
+          enum_values.push_back(*it);
+      }
+    }
+    if (!enum_values.empty()) {
+      text += '\"';
+      for (auto it = enum_values.begin(), e = enum_values.end(); it != e; ++it)
+        text += (*it)->name + ' ';
+      text[text.length() - 1] = '\"';
+      return true;
+    }
+  }
+
+  if (type.base_type == BASE_TYPE_BOOL) {
+    text += val != 0 ? "true" : "false";
+  } else {
+    text += NumToString(val);
+  }
+
+  return true;
+}
+
+// Print a vector or an array of JSON values, comma seperated, wrapped in "[]".
+template<typename T, typename Container>
+bool PrintContainer(const Container &c, size_t size, Type type, int indent,
+                    const IDLOptions &opts, std::string *_text) {
+  std::string &text = *_text;
+  text += "[";
+  text += NewLine(opts);
+  for (uoffset_t i = 0; i < size; i++) {
+    if (i) {
+      if (!opts.protobuf_ascii_alike) text += ",";
+      text += NewLine(opts);
+    }
+    text.append(indent + Indent(opts), ' ');
+    if (IsStruct(type)) {
+      if (!Print(reinterpret_cast<const void *>(c.Data() +
+                                                i * type.struct_def->bytesize),
+                 type, indent + Indent(opts), nullptr, opts, _text)) {
+        return false;
+      }
+    } else {
+      if (!Print(c[i], type, indent + Indent(opts), nullptr, opts, _text)) {
+        return false;
+      }
+    }
+  }
+  text += NewLine(opts);
+  text.append(indent, ' ');
+  text += "]";
+  return true;
+}
+
+template<typename T>
+bool PrintVector(const Vector<T> &v, Type type, int indent,
+                 const IDLOptions &opts, std::string *_text) {
+  return PrintContainer<T, Vector<T>>(v, v.size(), type, indent, opts, _text);
+}
+
+// Print an array a sequence of JSON values, comma separated, wrapped in "[]".
+template<typename T>
+bool PrintArray(const Array<T, 0xFFFF> &a, size_t size, Type type, int indent,
+                const IDLOptions &opts, std::string *_text) {
+  return PrintContainer<T, Array<T, 0xFFFF>>(a, size, type, indent, opts,
+                                             _text);
+}
+
+// Specialization of Print above for pointer types.
+template<>
+bool Print<const void *>(const void *val, Type type, int indent,
+                         Type *union_type, const IDLOptions &opts,
+                         std::string *_text) {
+  switch (type.base_type) {
+    case BASE_TYPE_UNION:
+      // If this assert hits, you have an corrupt buffer, a union type field
+      // was not present or was out of range.
+      FLATBUFFERS_ASSERT(union_type);
+      return Print<const void *>(val, *union_type, indent, nullptr, opts,
+                                 _text);
+    case BASE_TYPE_STRUCT:
+      if (!GenStruct(*type.struct_def, reinterpret_cast<const Table *>(val),
+                     indent, opts, _text)) {
+        return false;
+      }
+      break;
+    case BASE_TYPE_STRING: {
+      auto s = reinterpret_cast<const String *>(val);
+      if (!EscapeString(s->c_str(), s->size(), _text, opts.allow_non_utf8,
+                        opts.natural_utf8)) {
+        return false;
+      }
+      break;
+    }
+    case BASE_TYPE_VECTOR: {
+      const auto vec_type = type.VectorType();
+      // Call PrintVector above specifically for each element type:
+      // clang-format off
+      switch (vec_type.base_type) {
+        #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+          CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
+          case BASE_TYPE_ ## ENUM: \
+            if (!PrintVector<CTYPE>( \
+                  *reinterpret_cast<const Vector<CTYPE> *>(val), \
+                  vec_type, indent, opts, _text)) { \
+              return false; \
+            } \
+            break;
+          FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+        #undef FLATBUFFERS_TD
+      }
+      // clang-format on
+      break;
+    }
+    case BASE_TYPE_ARRAY: {
+      const auto vec_type = type.VectorType();
+      // Call PrintArray above specifically for each element type:
+      // clang-format off
+      switch (vec_type.base_type) {
+        #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+        CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
+        case BASE_TYPE_ ## ENUM: \
+          if (!PrintArray<CTYPE>( \
+              *reinterpret_cast<const Array<CTYPE, 0xFFFF> *>(val), \
+              type.fixed_length, \
+              vec_type, indent, opts, _text)) { \
+          return false; \
+          } \
+          break;
+        FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
+        FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
+        #undef FLATBUFFERS_TD
+        case BASE_TYPE_ARRAY: FLATBUFFERS_ASSERT(0);
+      }
+      // clang-format on
+      break;
+    }
+    default: FLATBUFFERS_ASSERT(0);
+  }
+  return true;
+}
+
+template<typename T> static T GetFieldDefault(const FieldDef &fd) {
+  T val;
+  auto check = StringToNumber(fd.value.constant.c_str(), &val);
+  (void)check;
+  FLATBUFFERS_ASSERT(check);
+  return val;
+}
+
+// Generate text for a scalar field.
+template<typename T>
+static bool GenField(const FieldDef &fd, const Table *table, bool fixed,
+                     const IDLOptions &opts, int indent, std::string *_text) {
+  return Print(
+      fixed ? reinterpret_cast<const Struct *>(table)->GetField<T>(
+                  fd.value.offset)
+            : table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)),
+      fd.value.type, indent, nullptr, opts, _text);
+}
+
+static bool GenStruct(const StructDef &struct_def, const Table *table,
+                      int indent, const IDLOptions &opts, std::string *_text);
+
+// Generate text for non-scalar field.
+static bool GenFieldOffset(const FieldDef &fd, const Table *table, bool fixed,
+                           int indent, Type *union_type, const IDLOptions &opts,
+                           std::string *_text) {
+  const void *val = nullptr;
+  if (fixed) {
+    // The only non-scalar fields in structs are structs or arrays.
+    FLATBUFFERS_ASSERT(IsStruct(fd.value.type) || IsArray(fd.value.type));
+    val = reinterpret_cast<const Struct *>(table)->GetStruct<const void *>(
+        fd.value.offset);
+  } else if (fd.flexbuffer) {
+    auto vec = table->GetPointer<const Vector<uint8_t> *>(fd.value.offset);
+    auto root = flexbuffers::GetRoot(vec->data(), vec->size());
+    root.ToString(true, opts.strict_json, *_text);
+    return true;
+  } else if (fd.nested_flatbuffer) {
+    auto vec = table->GetPointer<const Vector<uint8_t> *>(fd.value.offset);
+    auto root = GetRoot<Table>(vec->data());
+    return GenStruct(*fd.nested_flatbuffer, root, indent, opts, _text);
+  } else {
+    val = IsStruct(fd.value.type)
+              ? table->GetStruct<const void *>(fd.value.offset)
+              : table->GetPointer<const void *>(fd.value.offset);
+  }
+  return Print(val, fd.value.type, indent, union_type, opts, _text);
+}
+
+// Generate text for a struct or table, values separated by commas, indented,
+// and bracketed by "{}"
+static bool GenStruct(const StructDef &struct_def, const Table *table,
+                      int indent, const IDLOptions &opts, std::string *_text) {
+  std::string &text = *_text;
+  text += "{";
+  int fieldout = 0;
+  Type *union_type = nullptr;
+  for (auto it = struct_def.fields.vec.begin();
+       it != struct_def.fields.vec.end(); ++it) {
+    FieldDef &fd = **it;
+    auto is_present = struct_def.fixed || table->CheckField(fd.value.offset);
+    auto output_anyway = opts.output_default_scalars_in_json &&
+                         IsScalar(fd.value.type.base_type) && !fd.deprecated;
+    if (is_present || output_anyway) {
+      if (fieldout++) {
+        if (!opts.protobuf_ascii_alike) text += ",";
+      }
+      text += NewLine(opts);
+      text.append(indent + Indent(opts), ' ');
+      OutputIdentifier(fd.name, opts, _text);
+      if (!opts.protobuf_ascii_alike ||
+          (fd.value.type.base_type != BASE_TYPE_STRUCT &&
+           fd.value.type.base_type != BASE_TYPE_VECTOR))
+        text += ":";
+      text += " ";
+      switch (fd.value.type.base_type) {
+          // clang-format off
+          #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+            CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
+            case BASE_TYPE_ ## ENUM: \
+              if (!GenField<CTYPE>(fd, table, struct_def.fixed, \
+                                   opts, indent + Indent(opts), _text)) { \
+                return false; \
+              } \
+              break;
+          FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
+        #undef FLATBUFFERS_TD
+        // Generate drop-thru case statements for all pointer types:
+        #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+          CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
+          case BASE_TYPE_ ## ENUM:
+          FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
+          FLATBUFFERS_GEN_TYPE_ARRAY(FLATBUFFERS_TD)
+        #undef FLATBUFFERS_TD
+            if (!GenFieldOffset(fd, table, struct_def.fixed, indent + Indent(opts),
+                                union_type, opts, _text)) {
+              return false;
+            }
+            break;
+          // clang-format on
+      }
+      if (fd.value.type.base_type == BASE_TYPE_UTYPE) {
+        auto enum_val = fd.value.type.enum_def->ReverseLookup(
+            table->GetField<uint8_t>(fd.value.offset, 0), true);
+        union_type = enum_val ? &enum_val->union_type : nullptr;
+      }
+    }
+  }
+  text += NewLine(opts);
+  text.append(indent, ' ');
+  text += "}";
+  return true;
+}
+
+// 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;
+  FLATBUFFERS_ASSERT(parser.root_struct_def_);  // call SetRootType()
+  text.reserve(1024);               // Reduce amount of inevitable reallocs.
+  auto root = parser.opts.size_prefixed ?
+      GetSizePrefixedRoot<Table>(flatbuffer) : GetRoot<Table>(flatbuffer);
+  if (!GenStruct(*parser.root_struct_def_, root, 0, parser.opts, _text)) {
+    return false;
+  }
+  text += NewLine(parser.opts);
+  return true;
+}
+
+std::string TextFileName(const std::string &path,
+                         const std::string &file_name) {
+  return path + file_name + ".json";
+}
+
+bool GenerateTextFile(const Parser &parser, const std::string &path,
+                      const std::string &file_name) {
+  if (!parser.builder_.GetSize() || !parser.root_struct_def_) return true;
+  std::string text;
+  if (!GenerateText(parser, parser.builder_.GetBufferPointer(), &text)) {
+    return false;
+  }
+  return flatbuffers::SaveFile(TextFileName(path, file_name).c_str(), text,
+                               false);
+}
+
+std::string TextMakeRule(const Parser &parser, const std::string &path,
+                         const std::string &file_name) {
+  if (!parser.builder_.GetSize() || !parser.root_struct_def_) return "";
+  std::string filebase =
+      flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
+  std::string make_rule = TextFileName(path, filebase) + ": " + file_name;
+  auto included_files =
+      parser.GetIncludedFilesRecursive(parser.root_struct_def_->file);
+  for (auto it = included_files.begin(); it != included_files.end(); ++it) {
+    make_rule += " " + *it;
+  }
+  return make_rule;
+}
+
+}  // namespace flatbuffers
diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp
new file mode 100644
index 0000000..31b315c
--- /dev/null
+++ b/src/idl_parser.cpp
@@ -0,0 +1,3518 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <list>
+#include <string>
+#include <utility>
+
+#include <cmath>
+
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+namespace flatbuffers {
+
+// Reflects the version at the compiling time of binary(lib/dll/so).
+const char *FLATBUFFERS_VERSION() {
+  // clang-format off
+  return
+      FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "."
+      FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "."
+      FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION);
+  // clang-format on
+}
+
+const double kPi = 3.14159265358979323846;
+
+const char *const kTypeNames[] = {
+// clang-format off
+  #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+    CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
+    IDLTYPE,
+    FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+  #undef FLATBUFFERS_TD
+  // clang-format on
+  nullptr
+};
+
+const char kTypeSizes[] = {
+// clang-format off
+  #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+      CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
+      sizeof(CTYPE),
+    FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+  #undef FLATBUFFERS_TD
+  // clang-format on
+};
+
+// The enums in the reflection schema should match the ones we use internally.
+// Compare the last element to check if these go out of sync.
+static_assert(BASE_TYPE_UNION == static_cast<BaseType>(reflection::Union),
+              "enums don't match");
+
+// Any parsing calls have to be wrapped in this macro, which automates
+// handling of recursive error checking a bit. It will check the received
+// CheckedError object, and return straight away on error.
+#define ECHECK(call)           \
+  {                            \
+    auto ce = (call);          \
+    if (ce.Check()) return ce; \
+  }
+
+// These two functions are called hundreds of times below, so define a short
+// form:
+#define NEXT() ECHECK(Next())
+#define EXPECT(tok) ECHECK(Expect(tok))
+
+static bool ValidateUTF8(const std::string &str) {
+  const char *s = &str[0];
+  const char *const sEnd = s + str.length();
+  while (s < sEnd) {
+    if (FromUTF8(&s) < 0) { return false; }
+  }
+  return true;
+}
+
+// Convert an underscore_based_indentifier in to camelCase.
+// Also uppercases the first character if first is true.
+std::string MakeCamel(const std::string &in, bool first) {
+  std::string s;
+  for (size_t i = 0; i < in.length(); i++) {
+    if (!i && first)
+      s += static_cast<char>(toupper(in[0]));
+    else if (in[i] == '_' && i + 1 < in.length())
+      s += static_cast<char>(toupper(in[++i]));
+    else
+      s += in[i];
+  }
+  return s;
+}
+
+void DeserializeDoc( std::vector<std::string> &doc,
+                     const Vector<Offset<String>> *documentation) {
+  if (documentation == nullptr) return;
+  for (uoffset_t index = 0; index < documentation->size(); index++)
+    doc.push_back(documentation->Get(index)->str());
+}
+
+void Parser::Message(const std::string &msg) {
+  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()) + ")";
+  #else  // gcc alike
+    if (file_being_parsed_.length()) error_ += ":";
+    error_ += NumToString(line_) + ": " + NumToString(CursorPosition());
+  #endif
+  // clang-format on
+  error_ += ": " + msg;
+}
+
+void Parser::Warning(const std::string &msg) { Message("warning: " + msg); }
+
+CheckedError Parser::Error(const std::string &msg) {
+  Message("error: " + msg);
+  return CheckedError(true);
+}
+
+inline CheckedError NoError() { return CheckedError(false); }
+
+CheckedError Parser::RecurseError() {
+  return Error("maximum parsing recursion of " +
+               NumToString(FLATBUFFERS_MAX_PARSING_DEPTH) + " reached");
+}
+
+template<typename F> CheckedError Parser::Recurse(F f) {
+  if (recurse_protection_counter >= (FLATBUFFERS_MAX_PARSING_DEPTH))
+    return RecurseError();
+  recurse_protection_counter++;
+  auto ce = f();
+  recurse_protection_counter--;
+  return ce;
+}
+
+template<typename T> std::string TypeToIntervalString() {
+  return "[" + NumToString((flatbuffers::numeric_limits<T>::lowest)()) + "; " +
+         NumToString((flatbuffers::numeric_limits<T>::max)()) + "]";
+}
+
+// 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();
+  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,
+                                       Offset<void> *val) {
+  (void)parser;
+  *val = Offset<void>(atoi(s));
+  return NoError();
+}
+
+std::string Namespace::GetFullyQualifiedName(const std::string &name,
+                                             size_t max_components) const {
+  // Early exit if we don't have a defined namespace.
+  if (components.empty() || !max_components) { return name; }
+  std::string stream_str;
+  for (size_t i = 0; i < std::min(components.size(), max_components); i++) {
+    if (i) { stream_str += '.'; }
+    stream_str += std::string(components[i]);
+  }
+  if (name.length()) {
+    stream_str += '.';
+    stream_str += name;
+  }
+  return stream_str;
+}
+
+// Declare tokens we'll use. Single character tokens are represented by their
+// ascii character code (e.g. '{'), others above 256.
+// clang-format off
+#define FLATBUFFERS_GEN_TOKENS(TD) \
+  TD(Eof, 256, "end of file") \
+  TD(StringConstant, 257, "string constant") \
+  TD(IntegerConstant, 258, "integer constant") \
+  TD(FloatConstant, 259, "float constant") \
+  TD(Identifier, 260, "identifier")
+#ifdef __GNUC__
+__extension__  // Stop GCC complaining about trailing comma with -Wpendantic.
+#endif
+enum {
+  #define FLATBUFFERS_TOKEN(NAME, VALUE, STRING) kToken ## NAME = VALUE,
+    FLATBUFFERS_GEN_TOKENS(FLATBUFFERS_TOKEN)
+  #undef FLATBUFFERS_TOKEN
+};
+
+static std::string TokenToString(int t) {
+  static const char * const tokens[] = {
+    #define FLATBUFFERS_TOKEN(NAME, VALUE, STRING) STRING,
+      FLATBUFFERS_GEN_TOKENS(FLATBUFFERS_TOKEN)
+    #undef FLATBUFFERS_TOKEN
+    #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+      CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
+      IDLTYPE,
+      FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+    #undef FLATBUFFERS_TD
+  };
+  if (t < 256) {  // A single ascii char token.
+    std::string s;
+    s.append(1, static_cast<char>(t));
+    return s;
+  } else {       // Other tokens.
+    return tokens[t - 256];
+  }
+}
+// clang-format on
+
+std::string Parser::TokenToStringId(int t) const {
+  return t == kTokenIdentifier ? attribute_ : TokenToString(t);
+}
+
+// Parses exactly nibbles worth of hex digits into a number, or error.
+CheckedError Parser::ParseHexNum(int nibbles, uint64_t *val) {
+  FLATBUFFERS_ASSERT(nibbles > 0);
+  for (int i = 0; i < nibbles; i++)
+    if (!is_xdigit(cursor_[i]))
+      return Error("escape code must be followed by " + NumToString(nibbles) +
+                   " hex digits");
+  std::string target(cursor_, cursor_ + nibbles);
+  *val = StringToUInt(target.c_str(), 16);
+  cursor_ += nibbles;
+  return NoError();
+}
+
+CheckedError Parser::SkipByteOrderMark() {
+  if (static_cast<unsigned char>(*cursor_) != 0xef) return NoError();
+  cursor_++;
+  if (static_cast<unsigned char>(*cursor_) != 0xbb)
+    return Error("invalid utf-8 byte order mark");
+  cursor_++;
+  if (static_cast<unsigned char>(*cursor_) != 0xbf)
+    return Error("invalid utf-8 byte order mark");
+  cursor_++;
+  return NoError();
+}
+
+static inline bool IsIdentifierStart(char c) {
+  return is_alpha(c) || (c == '_');
+}
+
+CheckedError Parser::Next() {
+  doc_comment_.clear();
+  bool seen_newline = cursor_ == source_;
+  attribute_.clear();
+  attr_is_trivial_ascii_string_ = true;
+  for (;;) {
+    char c = *cursor_++;
+    token_ = c;
+    switch (c) {
+      case '\0':
+        cursor_--;
+        token_ = kTokenEof;
+        return NoError();
+      case ' ':
+      case '\r':
+      case '\t': break;
+      case '\n':
+        MarkNewLine();
+        seen_newline = true;
+        break;
+      case '{':
+      case '}':
+      case '(':
+      case ')':
+      case '[':
+      case ']':
+      case ',':
+      case ':':
+      case ';':
+      case '=': return NoError();
+      case '\"':
+      case '\'': {
+        int unicode_high_surrogate = -1;
+
+        while (*cursor_ != c) {
+          if (*cursor_ < ' ' && static_cast<signed char>(*cursor_) >= 0)
+            return Error("illegal character in string constant");
+          if (*cursor_ == '\\') {
+            attr_is_trivial_ascii_string_ = false;  // has escape sequence
+            cursor_++;
+            if (unicode_high_surrogate != -1 && *cursor_ != 'u') {
+              return Error(
+                  "illegal Unicode sequence (unpaired high surrogate)");
+            }
+            switch (*cursor_) {
+              case 'n':
+                attribute_ += '\n';
+                cursor_++;
+                break;
+              case 't':
+                attribute_ += '\t';
+                cursor_++;
+                break;
+              case 'r':
+                attribute_ += '\r';
+                cursor_++;
+                break;
+              case 'b':
+                attribute_ += '\b';
+                cursor_++;
+                break;
+              case 'f':
+                attribute_ += '\f';
+                cursor_++;
+                break;
+              case '\"':
+                attribute_ += '\"';
+                cursor_++;
+                break;
+              case '\'':
+                attribute_ += '\'';
+                cursor_++;
+                break;
+              case '\\':
+                attribute_ += '\\';
+                cursor_++;
+                break;
+              case '/':
+                attribute_ += '/';
+                cursor_++;
+                break;
+              case 'x': {  // Not in the JSON standard
+                cursor_++;
+                uint64_t val;
+                ECHECK(ParseHexNum(2, &val));
+                attribute_ += static_cast<char>(val);
+                break;
+              }
+              case 'u': {
+                cursor_++;
+                uint64_t val;
+                ECHECK(ParseHexNum(4, &val));
+                if (val >= 0xD800 && val <= 0xDBFF) {
+                  if (unicode_high_surrogate != -1) {
+                    return Error(
+                        "illegal Unicode sequence (multiple high surrogates)");
+                  } else {
+                    unicode_high_surrogate = static_cast<int>(val);
+                  }
+                } else if (val >= 0xDC00 && val <= 0xDFFF) {
+                  if (unicode_high_surrogate == -1) {
+                    return Error(
+                        "illegal Unicode sequence (unpaired low surrogate)");
+                  } else {
+                    int code_point = 0x10000 +
+                                     ((unicode_high_surrogate & 0x03FF) << 10) +
+                                     (val & 0x03FF);
+                    ToUTF8(code_point, &attribute_);
+                    unicode_high_surrogate = -1;
+                  }
+                } else {
+                  if (unicode_high_surrogate != -1) {
+                    return Error(
+                        "illegal Unicode sequence (unpaired high surrogate)");
+                  }
+                  ToUTF8(static_cast<int>(val), &attribute_);
+                }
+                break;
+              }
+              default: return Error("unknown escape code in string constant");
+            }
+          } else {  // printable chars + UTF-8 bytes
+            if (unicode_high_surrogate != -1) {
+              return Error(
+                  "illegal Unicode sequence (unpaired high surrogate)");
+            }
+            // reset if non-printable
+            attr_is_trivial_ascii_string_ &= check_ascii_range(*cursor_, ' ', '~');
+
+            attribute_ += *cursor_++;
+          }
+        }
+        if (unicode_high_surrogate != -1) {
+          return Error("illegal Unicode sequence (unpaired high surrogate)");
+        }
+        cursor_++;
+        if (!attr_is_trivial_ascii_string_ && !opts.allow_non_utf8 &&
+            !ValidateUTF8(attribute_)) {
+          return Error("illegal UTF-8 sequence");
+        }
+        token_ = kTokenStringConstant;
+        return NoError();
+      }
+      case '/':
+        if (*cursor_ == '/') {
+          const char *start = ++cursor_;
+          while (*cursor_ && *cursor_ != '\n' && *cursor_ != '\r') cursor_++;
+          if (*start == '/') {  // documentation comment
+            if (!seen_newline)
+              return Error(
+                  "a documentation comment should be on a line on its own");
+            doc_comment_.push_back(std::string(start + 1, cursor_));
+          }
+          break;
+        } else if (*cursor_ == '*') {
+          cursor_++;
+          // TODO: make nested.
+          while (*cursor_ != '*' || cursor_[1] != '/') {
+            if (*cursor_ == '\n') MarkNewLine();
+            if (!*cursor_) return Error("end of file in comment");
+            cursor_++;
+          }
+          cursor_ += 2;
+          break;
+        }
+        FLATBUFFERS_FALLTHROUGH(); // else fall thru
+      default:
+        const auto has_sign = (c == '+') || (c == '-');
+        // '-'/'+' and following identifier - can be a predefined constant like:
+        // NAN, INF, PI, etc.
+        if (IsIdentifierStart(c) || (has_sign && IsIdentifierStart(*cursor_))) {
+          // Collect all chars of an identifier:
+          const char *start = cursor_ - 1;
+          while (IsIdentifierStart(*cursor_) || is_digit(*cursor_)) cursor_++;
+          attribute_.append(start, cursor_);
+          token_ = has_sign ? kTokenStringConstant : kTokenIdentifier;
+          return NoError();
+        }
+
+        auto dot_lvl = (c == '.') ? 0 : 1;  // dot_lvl==0 <=> exactly one '.' seen
+        if (!dot_lvl && !is_digit(*cursor_)) return NoError(); // enum?
+        // Parser accepts hexadecimal-floating-literal (see C++ 5.13.4).
+        if (is_digit(c) || has_sign || !dot_lvl) {
+          const auto start = cursor_ - 1;
+          auto start_digits = !is_digit(c) ? cursor_ : cursor_ - 1;
+          if (!is_digit(c) && is_digit(*cursor_)){
+            start_digits = cursor_; // see digit in cursor_ position
+            c = *cursor_++;
+          }
+          // hex-float can't begind with '.'
+          auto use_hex = dot_lvl && (c == '0') && is_alpha_char(*cursor_, 'X');
+          if (use_hex) start_digits = ++cursor_;  // '0x' is the prefix, skip it
+          // Read an integer number or mantisa of float-point number.
+          do {
+            if (use_hex) {
+              while (is_xdigit(*cursor_)) cursor_++;
+            } else {
+              while (is_digit(*cursor_)) cursor_++;
+            }
+          } while ((*cursor_ == '.') && (++cursor_) && (--dot_lvl >= 0));
+          // Exponent of float-point number.
+          if ((dot_lvl >= 0) && (cursor_ > start_digits)) {
+            // The exponent suffix of hexadecimal float number is mandatory.
+            if (use_hex && !dot_lvl) start_digits = cursor_;
+            if ((use_hex && is_alpha_char(*cursor_, 'P')) ||
+                is_alpha_char(*cursor_, 'E')) {
+              dot_lvl = 0;  // Emulate dot to signal about float-point number.
+              cursor_++;
+              if (*cursor_ == '+' || *cursor_ == '-') cursor_++;
+              start_digits = cursor_;  // the exponent-part has to have digits
+              // Exponent is decimal integer number
+              while (is_digit(*cursor_)) cursor_++;
+              if (*cursor_ == '.') {
+                cursor_++;  // If see a dot treat it as part of invalid number.
+                dot_lvl = -1;  // Fall thru to Error().
+              }
+            }
+          }
+          // Finalize.
+          if ((dot_lvl >= 0) && (cursor_ > start_digits)) {
+            attribute_.append(start, cursor_);
+            token_ = dot_lvl ? kTokenIntegerConstant : kTokenFloatConstant;
+            return NoError();
+          } else {
+            return Error("invalid number: " + std::string(start, cursor_));
+          }
+        }
+        std::string ch;
+        ch = c;
+        if (false == check_ascii_range(c, ' ', '~')) ch = "code: " + NumToString(c);
+        return Error("illegal character: " + ch);
+    }
+  }
+}
+
+// Check if a given token is next.
+bool Parser::Is(int t) const { return t == token_; }
+
+bool Parser::IsIdent(const char *id) const {
+  return token_ == kTokenIdentifier && attribute_ == id;
+}
+
+// Expect a given token to be next, consume it, or error if not present.
+CheckedError Parser::Expect(int t) {
+  if (t != token_) {
+    return Error("expecting: " + TokenToString(t) +
+                 " instead got: " + TokenToStringId(token_));
+  }
+  NEXT();
+  return NoError();
+}
+
+CheckedError Parser::ParseNamespacing(std::string *id, std::string *last) {
+  while (Is('.')) {
+    NEXT();
+    *id += ".";
+    *id += attribute_;
+    if (last) *last = attribute_;
+    EXPECT(kTokenIdentifier);
+  }
+  return NoError();
+}
+
+EnumDef *Parser::LookupEnum(const std::string &id) {
+  // Search thru parent namespaces.
+  for (int components = static_cast<int>(current_namespace_->components.size());
+       components >= 0; components--) {
+    auto ed = enums_.Lookup(
+        current_namespace_->GetFullyQualifiedName(id, components));
+    if (ed) return ed;
+  }
+  return nullptr;
+}
+
+StructDef *Parser::LookupStruct(const std::string &id) const {
+  auto sd = structs_.Lookup(id);
+  if (sd) sd->refcount++;
+  return sd;
+}
+
+CheckedError Parser::ParseTypeIdent(Type &type) {
+  std::string id = attribute_;
+  EXPECT(kTokenIdentifier);
+  ECHECK(ParseNamespacing(&id, nullptr));
+  auto enum_def = LookupEnum(id);
+  if (enum_def) {
+    type = enum_def->underlying_type;
+    if (enum_def->is_union) type.base_type = BASE_TYPE_UNION;
+  } else {
+    type.base_type = BASE_TYPE_STRUCT;
+    type.struct_def = LookupCreateStruct(id);
+  }
+  return NoError();
+}
+
+// Parse any IDL type.
+CheckedError Parser::ParseType(Type &type) {
+  if (token_ == kTokenIdentifier) {
+    if (IsIdent("bool")) {
+      type.base_type = BASE_TYPE_BOOL;
+      NEXT();
+    } else if (IsIdent("byte") || IsIdent("int8")) {
+      type.base_type = BASE_TYPE_CHAR;
+      NEXT();
+    } else if (IsIdent("ubyte") || IsIdent("uint8")) {
+      type.base_type = BASE_TYPE_UCHAR;
+      NEXT();
+    } else if (IsIdent("short") || IsIdent("int16")) {
+      type.base_type = BASE_TYPE_SHORT;
+      NEXT();
+    } else if (IsIdent("ushort") || IsIdent("uint16")) {
+      type.base_type = BASE_TYPE_USHORT;
+      NEXT();
+    } else if (IsIdent("int") || IsIdent("int32")) {
+      type.base_type = BASE_TYPE_INT;
+      NEXT();
+    } else if (IsIdent("uint") || IsIdent("uint32")) {
+      type.base_type = BASE_TYPE_UINT;
+      NEXT();
+    } else if (IsIdent("long") || IsIdent("int64")) {
+      type.base_type = BASE_TYPE_LONG;
+      NEXT();
+    } else if (IsIdent("ulong") || IsIdent("uint64")) {
+      type.base_type = BASE_TYPE_ULONG;
+      NEXT();
+    } else if (IsIdent("float") || IsIdent("float32")) {
+      type.base_type = BASE_TYPE_FLOAT;
+      NEXT();
+    } else if (IsIdent("double") || IsIdent("float64")) {
+      type.base_type = BASE_TYPE_DOUBLE;
+      NEXT();
+    } else if (IsIdent("string")) {
+      type.base_type = BASE_TYPE_STRING;
+      NEXT();
+    } else {
+      ECHECK(ParseTypeIdent(type));
+    }
+  } else if (token_ == '[') {
+    NEXT();
+    Type subtype;
+    ECHECK(Recurse([&]() { return ParseType(subtype); }));
+    if (IsSeries(subtype)) {
+      // We could support this, but it will complicate things, and it's
+      // easier to work around with a struct around the inner vector.
+      return Error("nested vector types not supported (wrap in table first)");
+    }
+    if (token_ == ':') {
+      NEXT();
+      if (token_ != kTokenIntegerConstant) {
+        return Error("length of fixed-length array must be an integer value");
+      }
+      uint16_t fixed_length = 0;
+      bool check = StringToNumber(attribute_.c_str(), &fixed_length);
+      if (!check || fixed_length < 1) {
+        return Error(
+            "length of fixed-length array must be positive and fit to "
+            "uint16_t type");
+      }
+      // Check if enum arrays are used in C++ without specifying --scoped-enums
+      if ((opts.lang_to_generate & IDLOptions::kCpp) && !opts.scoped_enums &&
+          IsEnum(subtype)) {
+        return Error(
+            "--scoped-enums must be enabled to use enum arrays in C++\n");
+      }
+      type = Type(BASE_TYPE_ARRAY, subtype.struct_def, subtype.enum_def,
+                  fixed_length);
+      NEXT();
+    } else {
+      type = Type(BASE_TYPE_VECTOR, subtype.struct_def, subtype.enum_def);
+    }
+    type.element = subtype.base_type;
+    EXPECT(']');
+  } else {
+    return Error("illegal type syntax");
+  }
+  return NoError();
+}
+
+CheckedError Parser::AddField(StructDef &struct_def, const std::string &name,
+                              const Type &type, FieldDef **dest) {
+  auto &field = *new FieldDef();
+  field.value.offset =
+      FieldIndexToOffset(static_cast<voffset_t>(struct_def.fields.vec.size()));
+  field.name = name;
+  field.file = struct_def.file;
+  field.value.type = type;
+  if (struct_def.fixed) {  // statically compute the field offset
+    auto size = InlineSize(type);
+    auto alignment = InlineAlignment(type);
+    // structs_ need to have a predictable format, so we need to align to
+    // the largest scalar
+    struct_def.minalign = std::max(struct_def.minalign, alignment);
+    struct_def.PadLastField(alignment);
+    field.value.offset = static_cast<voffset_t>(struct_def.bytesize);
+    struct_def.bytesize += size;
+  }
+  if (struct_def.fields.Add(name, &field))
+    return Error("field already exists: " + name);
+  *dest = &field;
+  return NoError();
+}
+
+CheckedError Parser::ParseField(StructDef &struct_def) {
+  std::string name = attribute_;
+
+  if (LookupStruct(name))
+    return Error("field name can not be the same as table/struct name");
+
+  std::vector<std::string> dc = doc_comment_;
+  EXPECT(kTokenIdentifier);
+  EXPECT(':');
+  Type type;
+  ECHECK(ParseType(type));
+
+  if (struct_def.fixed && !IsScalar(type.base_type) && !IsStruct(type) &&
+      !IsArray(type))
+    return Error("structs_ may contain only scalar or struct fields");
+
+  if (!struct_def.fixed && IsArray(type))
+    return Error("fixed-length array in table must be wrapped in struct");
+
+  if (IsArray(type) && !SupportsAdvancedArrayFeatures()) {
+    return Error(
+        "Arrays are not yet supported in all "
+        "the specified programming languages.");
+  }
+
+  FieldDef *typefield = nullptr;
+  if (type.base_type == BASE_TYPE_UNION) {
+    // For union fields, add a second auto-generated field to hold the type,
+    // with a special suffix.
+    ECHECK(AddField(struct_def, name + UnionTypeFieldSuffix(),
+                    type.enum_def->underlying_type, &typefield));
+  } else if (type.base_type == BASE_TYPE_VECTOR &&
+             type.element == BASE_TYPE_UNION) {
+    // Only cpp, js and ts supports the union vector feature so far.
+    if (!SupportsAdvancedUnionFeatures()) {
+      return Error(
+          "Vectors of unions are not yet supported in all "
+          "the specified programming languages.");
+    }
+    // For vector of union fields, add a second auto-generated vector field to
+    // hold the types, with a special suffix.
+    Type union_vector(BASE_TYPE_VECTOR, nullptr, type.enum_def);
+    union_vector.element = BASE_TYPE_UTYPE;
+    ECHECK(AddField(struct_def, name + UnionTypeFieldSuffix(), union_vector,
+                    &typefield));
+  }
+
+  FieldDef *field;
+  ECHECK(AddField(struct_def, name, type, &field));
+
+  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");
+  }
+  // Append .0 if the value has not it (skip hex and scientific floats).
+  // This suffix needed for generated C++ code.
+  if (IsFloat(type.base_type)) {
+    auto &text = field->value.constant;
+    FLATBUFFERS_ASSERT(false == text.empty());
+    auto s = text.c_str();
+    while(*s == ' ') s++;
+    if (*s == '-' || *s == '+') s++;
+    // 1) A float constants (nan, inf, pi, etc) is a kind of identifier.
+    // 2) A float number needn't ".0" at the end if it has exponent.
+    if ((false == IsIdentifierStart(*s)) &&
+        (std::string::npos == field->value.constant.find_first_of(".eEpP"))) {
+      field->value.constant += ".0";
+    }
+  }
+  if (type.enum_def) {
+    // The type.base_type can only be scalar, union, array or vector.
+    // Table, struct or string can't have enum_def.
+    // Default value of union and vector in NONE, NULL translated to "0".
+    FLATBUFFERS_ASSERT(IsInteger(type.base_type) ||
+                       (type.base_type == BASE_TYPE_UNION) ||
+                       (type.base_type == BASE_TYPE_VECTOR) ||
+                       (type.base_type == BASE_TYPE_ARRAY));
+    if (type.base_type == BASE_TYPE_VECTOR) {
+      // Vector can't use initialization list.
+      FLATBUFFERS_ASSERT(field->value.constant == "0");
+    } else {
+      // All unions should have the NONE ("0") enum value.
+      auto in_enum = type.enum_def->attributes.Lookup("bit_flags") ||
+                     type.enum_def->FindByValue(field->value.constant);
+      if (false == in_enum)
+        return Error("default value of " + field->value.constant +
+                     " for field " + name + " is not part of enum " +
+                     type.enum_def->name);
+    }
+  }
+
+  field->doc_comment = dc;
+  ECHECK(ParseMetaData(&field->attributes));
+  field->deprecated = field->attributes.Lookup("deprecated") != nullptr;
+  auto hash_name = field->attributes.Lookup("hash");
+  if (hash_name) {
+    switch ((type.base_type == BASE_TYPE_VECTOR) ? type.element : type.base_type) {
+      case BASE_TYPE_SHORT:
+      case BASE_TYPE_USHORT: {
+        if (FindHashFunction16(hash_name->constant.c_str()) == nullptr)
+          return Error("Unknown hashing algorithm for 16 bit types: " +
+                       hash_name->constant);
+        break;
+      }
+      case BASE_TYPE_INT:
+      case BASE_TYPE_UINT: {
+        if (FindHashFunction32(hash_name->constant.c_str()) == nullptr)
+          return Error("Unknown hashing algorithm for 32 bit types: " +
+                       hash_name->constant);
+        break;
+      }
+      case BASE_TYPE_LONG:
+      case BASE_TYPE_ULONG: {
+        if (FindHashFunction64(hash_name->constant.c_str()) == nullptr)
+          return Error("Unknown hashing algorithm for 64 bit types: " +
+                       hash_name->constant);
+        break;
+      }
+      default:
+        return Error(
+            "only short, ushort, int, uint, long and ulong data types support hashing.");
+    }
+  }
+  auto cpp_type = field->attributes.Lookup("cpp_type");
+  if (cpp_type) {
+    if (!hash_name)
+      return Error("cpp_type can only be used with a hashed field");
+    /// forcing cpp_ptr_type to 'naked' if unset
+    auto cpp_ptr_type = field->attributes.Lookup("cpp_ptr_type");
+    if (!cpp_ptr_type) {
+      auto val = new Value();
+      val->type = cpp_type->type;
+      val->constant = "naked";
+      field->attributes.Add("cpp_ptr_type", val);
+    }
+  }
+  if (field->deprecated && struct_def.fixed)
+    return Error("can't deprecate fields in a struct");
+  field->required = field->attributes.Lookup("required") != nullptr;
+  if (field->required &&
+      (struct_def.fixed || IsScalar(type.base_type)))
+    return Error("only non-scalar fields in tables may be 'required'");
+  field->key = field->attributes.Lookup("key") != nullptr;
+  if (field->key) {
+    if (struct_def.has_key) return Error("only one field may be set as 'key'");
+    struct_def.has_key = true;
+    if (!IsScalar(type.base_type)) {
+      field->required = true;
+      if (type.base_type != BASE_TYPE_STRING)
+        return Error("'key' field must be string or scalar type");
+    }
+  }
+  field->shared = field->attributes.Lookup("shared") != nullptr;
+  if (field->shared && field->value.type.base_type != BASE_TYPE_STRING)
+    return Error("shared can only be defined on strings");
+
+  auto field_native_custom_alloc =
+      field->attributes.Lookup("native_custom_alloc");
+  if (field_native_custom_alloc)
+    return Error(
+        "native_custom_alloc can only be used with a table or struct "
+        "definition");
+
+  field->native_inline = field->attributes.Lookup("native_inline") != nullptr;
+  if (field->native_inline && !IsStruct(field->value.type))
+    return Error("native_inline can only be defined on structs");
+
+  auto nested = field->attributes.Lookup("nested_flatbuffer");
+  if (nested) {
+    if (nested->type.base_type != BASE_TYPE_STRING)
+      return Error(
+          "nested_flatbuffer attribute must be a string (the root type)");
+    if (type.base_type != BASE_TYPE_VECTOR || type.element != BASE_TYPE_UCHAR)
+      return Error(
+          "nested_flatbuffer attribute may only apply to a vector of ubyte");
+    // This will cause an error if the root type of the nested flatbuffer
+    // wasn't defined elsewhere.
+    field->nested_flatbuffer = LookupCreateStruct(nested->constant);
+  }
+
+  if (field->attributes.Lookup("flexbuffer")) {
+    field->flexbuffer = true;
+    uses_flexbuffers_ = true;
+    if (type.base_type != BASE_TYPE_VECTOR ||
+        type.element != BASE_TYPE_UCHAR)
+      return Error("flexbuffer attribute may only apply to a vector of ubyte");
+  }
+
+  if (typefield) {
+    if (!IsScalar(typefield->value.type.base_type)) {
+      // this is a union vector field
+      typefield->required = field->required;
+    }
+    // If this field is a union, and it has a manually assigned id,
+    // the automatically added type field should have an id as well (of N - 1).
+    auto attr = field->attributes.Lookup("id");
+    if (attr) {
+      auto id = atoi(attr->constant.c_str());
+      auto val = new Value();
+      val->type = attr->type;
+      val->constant = NumToString(id - 1);
+      typefield->attributes.Add("id", val);
+    }
+  }
+
+  EXPECT(';');
+  return NoError();
+}
+
+CheckedError Parser::ParseString(Value &val) {
+  auto s = attribute_;
+  EXPECT(kTokenStringConstant);
+  val.constant = NumToString(builder_.CreateString(s).o);
+  return NoError();
+}
+
+CheckedError Parser::ParseComma() {
+  if (!opts.protobuf_ascii_alike) EXPECT(',');
+  return NoError();
+}
+
+CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
+                                   size_t parent_fieldn,
+                                   const StructDef *parent_struct_def,
+                                   uoffset_t count,
+                                   bool inside_vector) {
+  switch (val.type.base_type) {
+    case BASE_TYPE_UNION: {
+      FLATBUFFERS_ASSERT(field);
+      std::string constant;
+      Vector<uint8_t> *vector_of_union_types = nullptr;
+      // Find corresponding type field we may have already parsed.
+      for (auto elem = field_stack_.rbegin() + count;
+           elem != field_stack_.rbegin() + parent_fieldn + count; ++elem) {
+        auto &type = elem->second->value.type;
+        if (type.enum_def == val.type.enum_def) {
+          if (inside_vector) {
+            if (type.base_type == BASE_TYPE_VECTOR &&
+                type.element == BASE_TYPE_UTYPE) {
+              // Vector of union type field.
+              uoffset_t offset;
+              ECHECK(atot(elem->first.constant.c_str(), *this, &offset));
+              vector_of_union_types = reinterpret_cast<Vector<uint8_t> *>(
+                                        builder_.GetCurrentBufferPointer() +
+                                        builder_.GetSize() - offset);
+              break;
+            }
+          } else {
+            if (type.base_type == BASE_TYPE_UTYPE) {
+              // Union type field.
+              constant = elem->first.constant;
+              break;
+            }
+          }
+        }
+      }
+      if (constant.empty() && !inside_vector) {
+        // We haven't seen the type field yet. Sadly a lot of JSON writers
+        // output these in alphabetical order, meaning it comes after this
+        // value. So we scan past the value to find it, then come back here.
+        // We currently don't do this for vectors of unions because the
+        // scanning/serialization logic would get very complicated.
+        auto type_name = field->name + UnionTypeFieldSuffix();
+        FLATBUFFERS_ASSERT(parent_struct_def);
+        auto type_field = parent_struct_def->fields.Lookup(type_name);
+        FLATBUFFERS_ASSERT(type_field);  // Guaranteed by ParseField().
+        // Remember where we are in the source file, so we can come back here.
+        auto backup = *static_cast<ParserState *>(this);
+        ECHECK(SkipAnyJsonValue());  // The table.
+        ECHECK(ParseComma());
+        auto next_name = attribute_;
+        if (Is(kTokenStringConstant)) {
+          NEXT();
+        } else {
+          EXPECT(kTokenIdentifier);
+        }
+        if (next_name == type_name) {
+          EXPECT(':');
+          Value type_val = type_field->value;
+          ECHECK(ParseAnyValue(type_val, type_field, 0, nullptr, 0));
+          constant = type_val.constant;
+          // Got the information we needed, now rewind:
+          *static_cast<ParserState *>(this) = backup;
+        }
+      }
+      if (constant.empty() && !vector_of_union_types) {
+        return Error("missing type field for this union value: " +
+                     field->name);
+      }
+      uint8_t enum_idx;
+      if (vector_of_union_types) {
+        enum_idx = vector_of_union_types->Get(count);
+      } else {
+        ECHECK(atot(constant.c_str(), *this, &enum_idx));
+      }
+      auto enum_val = val.type.enum_def->ReverseLookup(enum_idx, true);
+      if (!enum_val) return Error("illegal type id for: " + field->name);
+      if (enum_val->union_type.base_type == BASE_TYPE_STRUCT) {
+        ECHECK(ParseTable(*enum_val->union_type.struct_def, &val.constant,
+                          nullptr));
+        if (enum_val->union_type.struct_def->fixed) {
+          // All BASE_TYPE_UNION values are offsets, so turn this into one.
+          SerializeStruct(*enum_val->union_type.struct_def, val);
+          builder_.ClearOffsets();
+          val.constant = NumToString(builder_.GetSize());
+        }
+      } else if (enum_val->union_type.base_type == BASE_TYPE_STRING) {
+        ECHECK(ParseString(val));
+      } else {
+        FLATBUFFERS_ASSERT(false);
+      }
+      break;
+    }
+    case BASE_TYPE_STRUCT:
+      ECHECK(ParseTable(*val.type.struct_def, &val.constant, nullptr));
+      break;
+    case BASE_TYPE_STRING: {
+      ECHECK(ParseString(val));
+      break;
+    }
+    case BASE_TYPE_VECTOR: {
+      uoffset_t off;
+      ECHECK(ParseVector(val.type.VectorType(), &off, field, parent_fieldn));
+      val.constant = NumToString(off);
+      break;
+    }
+    case BASE_TYPE_ARRAY: {
+      ECHECK(ParseArray(val));
+      break;
+    }
+    case BASE_TYPE_INT:
+    case BASE_TYPE_UINT:
+    case BASE_TYPE_LONG:
+    case BASE_TYPE_ULONG: {
+      if (field && field->attributes.Lookup("hash") &&
+          (token_ == kTokenIdentifier || token_ == kTokenStringConstant)) {
+        ECHECK(ParseHash(val, field));
+      } else {
+        ECHECK(ParseSingleValue(field ? &field->name : nullptr, val, false));
+      }
+      break;
+    }
+    default:
+      ECHECK(ParseSingleValue(field ? &field->name : nullptr, val, false));
+      break;
+  }
+  return NoError();
+}
+
+void Parser::SerializeStruct(const StructDef &struct_def, const Value &val) {
+  SerializeStruct(builder_, struct_def, val);
+}
+
+void Parser::SerializeStruct(FlatBufferBuilder &builder,
+                             const StructDef &struct_def, const Value &val) {
+  FLATBUFFERS_ASSERT(val.constant.length() == struct_def.bytesize);
+  builder.Align(struct_def.minalign);
+  builder.PushBytes(reinterpret_cast<const uint8_t *>(val.constant.c_str()),
+                    struct_def.bytesize);
+  builder.AddStructOffset(val.offset, builder.GetSize());
+}
+
+template <typename F>
+CheckedError Parser::ParseTableDelimiters(size_t &fieldn,
+                                          const StructDef *struct_def,
+                                          F body) {
+  // We allow tables both as JSON object{ .. } with field names
+  // or vector[..] with all fields in order
+  char terminator = '}';
+  bool is_nested_vector = struct_def && Is('[');
+  if (is_nested_vector) {
+    NEXT();
+    terminator = ']';
+  } else {
+    EXPECT('{');
+  }
+  for (;;) {
+    if ((!opts.strict_json || !fieldn) && Is(terminator)) break;
+    std::string name;
+    if (is_nested_vector) {
+      if (fieldn >= struct_def->fields.vec.size()) {
+        return Error("too many unnamed fields in nested array");
+      }
+      name = struct_def->fields.vec[fieldn]->name;
+    } else {
+      name = attribute_;
+      if (Is(kTokenStringConstant)) {
+        NEXT();
+      } else {
+        EXPECT(opts.strict_json ? kTokenStringConstant : kTokenIdentifier);
+      }
+      if (!opts.protobuf_ascii_alike || !(Is('{') || Is('['))) EXPECT(':');
+    }
+    ECHECK(body(name, fieldn, struct_def));
+    if (Is(terminator)) break;
+    ECHECK(ParseComma());
+  }
+  NEXT();
+  if (is_nested_vector && fieldn != struct_def->fields.vec.size()) {
+    return Error("wrong number of unnamed fields in table vector");
+  }
+  return NoError();
+}
+
+CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
+                                uoffset_t *ovalue) {
+  size_t fieldn_outer = 0;
+  auto err = ParseTableDelimiters(
+      fieldn_outer, &struct_def,
+      [&](const std::string &name, size_t &fieldn,
+          const StructDef *struct_def_inner) -> CheckedError {
+        if (name == "$schema") {
+          ECHECK(Expect(kTokenStringConstant));
+          return NoError();
+        }
+        auto field = struct_def_inner->fields.Lookup(name);
+        if (!field) {
+          if (!opts.skip_unexpected_fields_in_json) {
+            return Error("unknown field: " + name);
+          } else {
+            ECHECK(SkipAnyJsonValue());
+          }
+        } else {
+          if (IsIdent("null") && !IsScalar(field->value.type.base_type)) {
+            ECHECK(Next());  // Ignore this field.
+          } else {
+            Value val = field->value;
+            if (field->flexbuffer) {
+              flexbuffers::Builder builder(1024,
+                                           flexbuffers::BUILDER_FLAG_SHARE_ALL);
+              ECHECK(ParseFlexBufferValue(&builder));
+              builder.Finish();
+              // Force alignment for nested flexbuffer
+              builder_.ForceVectorAlignment(builder.GetSize(), sizeof(uint8_t),
+                                            sizeof(largest_scalar_t));
+              auto off = builder_.CreateVector(builder.GetBuffer());
+              val.constant = NumToString(off.o);
+            } else if (field->nested_flatbuffer) {
+              ECHECK(
+                  ParseNestedFlatbuffer(val, field, fieldn, struct_def_inner));
+            } else {
+              ECHECK(Recurse([&]() {
+                return ParseAnyValue(val, field, fieldn, struct_def_inner, 0);
+              }));
+            }
+            // Hardcoded insertion-sort with error-check.
+            // If fields are specified in order, then this loop exits
+            // immediately.
+            auto elem = field_stack_.rbegin();
+            for (; elem != field_stack_.rbegin() + fieldn; ++elem) {
+              auto existing_field = elem->second;
+              if (existing_field == field)
+                return Error("field set more than once: " + field->name);
+              if (existing_field->value.offset < field->value.offset) break;
+            }
+            // Note: elem points to before the insertion point, thus .base()
+            // points to the correct spot.
+            field_stack_.insert(elem.base(), std::make_pair(val, field));
+            fieldn++;
+          }
+        }
+        return NoError();
+      });
+  ECHECK(err);
+
+  // Check if all required fields are parsed.
+  for (auto field_it = struct_def.fields.vec.begin();
+       field_it != struct_def.fields.vec.end(); ++field_it) {
+    auto required_field = *field_it;
+    if (!required_field->required) { continue; }
+    bool found = false;
+    for (auto pf_it = field_stack_.end() - fieldn_outer;
+         pf_it != field_stack_.end(); ++pf_it) {
+      auto parsed_field = pf_it->second;
+      if (parsed_field == required_field) {
+        found = true;
+        break;
+      }
+    }
+    if (!found) {
+      return Error("required field is missing: " + required_field->name +
+                   " in " + struct_def.name);
+    }
+  }
+
+  if (struct_def.fixed && fieldn_outer != struct_def.fields.vec.size())
+    return Error("struct: wrong number of initializers: " + struct_def.name);
+
+  auto start = struct_def.fixed ? builder_.StartStruct(struct_def.minalign)
+                                : builder_.StartTable();
+
+  for (size_t size = struct_def.sortbysize ? sizeof(largest_scalar_t) : 1; size;
+       size /= 2) {
+    // Go through elements in reverse, since we're building the data backwards.
+    for (auto it = field_stack_.rbegin();
+         it != field_stack_.rbegin() + fieldn_outer; ++it) {
+      auto &field_value = it->first;
+      auto field = it->second;
+      if (!struct_def.sortbysize ||
+          size == SizeOf(field_value.type.base_type)) {
+        switch (field_value.type.base_type) {
+          // clang-format off
+          #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+            CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
+            case BASE_TYPE_ ## ENUM: \
+              builder_.Pad(field->padding); \
+              if (struct_def.fixed) { \
+                CTYPE val; \
+                ECHECK(atot(field_value.constant.c_str(), *this, &val)); \
+                builder_.PushElement(val); \
+              } else { \
+                CTYPE val, valdef; \
+                ECHECK(atot(field_value.constant.c_str(), *this, &val)); \
+                ECHECK(atot(field->value.constant.c_str(), *this, &valdef)); \
+                builder_.AddElement(field_value.offset, val, valdef); \
+              } \
+              break;
+            FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD);
+          #undef FLATBUFFERS_TD
+          #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+            CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
+            case BASE_TYPE_ ## ENUM: \
+              builder_.Pad(field->padding); \
+              if (IsStruct(field->value.type)) { \
+                SerializeStruct(*field->value.type.struct_def, field_value); \
+              } else { \
+                CTYPE val; \
+                ECHECK(atot(field_value.constant.c_str(), *this, &val)); \
+                builder_.AddOffset(field_value.offset, val); \
+              } \
+              break;
+            FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD);
+          #undef FLATBUFFERS_TD
+            case BASE_TYPE_ARRAY:
+              builder_.Pad(field->padding);
+              builder_.PushBytes(
+                reinterpret_cast<const uint8_t*>(field_value.constant.c_str()),
+                InlineSize(field_value.type));
+              break;
+              // clang-format on
+        }
+      }
+    }
+  }
+  for (size_t i = 0; i < fieldn_outer; i++) field_stack_.pop_back();
+
+  if (struct_def.fixed) {
+    builder_.ClearOffsets();
+    builder_.EndStruct();
+    FLATBUFFERS_ASSERT(value);
+    // Temporarily store this struct in the value string, since it is to
+    // be serialized in-place elsewhere.
+    value->assign(
+        reinterpret_cast<const char *>(builder_.GetCurrentBufferPointer()),
+        struct_def.bytesize);
+    builder_.PopBytes(struct_def.bytesize);
+    FLATBUFFERS_ASSERT(!ovalue);
+  } else {
+    auto val = builder_.EndTable(start);
+    if (ovalue) *ovalue = val;
+    if (value) *value = NumToString(val);
+  }
+  return NoError();
+}
+
+template <typename F>
+CheckedError Parser::ParseVectorDelimiters(uoffset_t &count, F body) {
+  EXPECT('[');
+  for (;;) {
+    if ((!opts.strict_json || !count) && Is(']')) break;
+    ECHECK(body(count));
+    count++;
+    if (Is(']')) break;
+    ECHECK(ParseComma());
+  }
+  NEXT();
+  return NoError();
+}
+
+CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue,
+                                 FieldDef *field, size_t fieldn) {
+  uoffset_t count = 0;
+  auto err = ParseVectorDelimiters(count, [&](uoffset_t &) -> CheckedError {
+    Value val;
+    val.type = type;
+    ECHECK(Recurse([&]() {
+      return ParseAnyValue(val, field, fieldn, nullptr, count, true);
+    }));
+    field_stack_.push_back(std::make_pair(val, nullptr));
+    return NoError();
+  });
+  ECHECK(err);
+
+  builder_.StartVector(count * InlineSize(type) / InlineAlignment(type),
+                       InlineAlignment(type));
+  for (uoffset_t i = 0; i < count; i++) {
+    // start at the back, since we're building the data backwards.
+    auto &val = field_stack_.back().first;
+    switch (val.type.base_type) {
+      // clang-format off
+      #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+        CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
+        case BASE_TYPE_ ## ENUM: \
+          if (IsStruct(val.type)) SerializeStruct(*val.type.struct_def, val); \
+          else { \
+             CTYPE elem; \
+             ECHECK(atot(val.constant.c_str(), *this, &elem)); \
+             builder_.PushElement(elem); \
+          } \
+          break;
+        FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+      #undef FLATBUFFERS_TD
+      // clang-format on
+    }
+    field_stack_.pop_back();
+  }
+
+  builder_.ClearOffsets();
+  *ovalue = builder_.EndVector(count);
+  return NoError();
+}
+
+CheckedError Parser::ParseArray(Value &array) {
+  std::vector<Value> stack;
+  FlatBufferBuilder builder;
+  const auto &type = array.type.VectorType();
+  auto length = array.type.fixed_length;
+  uoffset_t count = 0;
+  auto err = ParseVectorDelimiters(count, [&](uoffset_t &) -> CheckedError {
+    vector_emplace_back(&stack, Value());
+    auto &val = stack.back();
+    val.type = type;
+    if (IsStruct(type)) {
+      ECHECK(ParseTable(*val.type.struct_def, &val.constant, nullptr));
+    } else {
+      ECHECK(ParseSingleValue(nullptr, val, false));
+    }
+    return NoError();
+  });
+  ECHECK(err);
+  if (length != count) return Error("Fixed-length array size is incorrect.");
+
+  for (auto it = stack.rbegin(); it != stack.rend(); ++it) {
+    auto &val = *it;
+    // clang-format off
+    switch (val.type.base_type) {
+      #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+        CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
+        case BASE_TYPE_ ## ENUM: \
+          if (IsStruct(val.type)) { \
+            SerializeStruct(builder, *val.type.struct_def, val); \
+          } else { \
+            CTYPE elem; \
+            ECHECK(atot(val.constant.c_str(), *this, &elem)); \
+            builder.PushElement(elem); \
+          } \
+        break;
+        FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+      #undef FLATBUFFERS_TD
+      default: FLATBUFFERS_ASSERT(0);
+    }
+    // clang-format on
+  }
+
+  array.constant.assign(
+      reinterpret_cast<const char *>(builder.GetCurrentBufferPointer()),
+      InlineSize(array.type));
+  return NoError();
+}
+
+CheckedError Parser::ParseNestedFlatbuffer(Value &val, FieldDef *field,
+                                           size_t fieldn,
+                                           const StructDef *parent_struct_def) {
+  if (token_ == '[') {  // backwards compat for 'legacy' ubyte buffers
+    ECHECK(ParseAnyValue(val, field, fieldn, parent_struct_def, 0));
+  } else {
+    auto cursor_at_value_begin = cursor_;
+    ECHECK(SkipAnyJsonValue());
+    std::string substring(cursor_at_value_begin - 1, cursor_ - 1);
+
+    // Create and initialize new parser
+    Parser nested_parser;
+    FLATBUFFERS_ASSERT(field->nested_flatbuffer);
+    nested_parser.root_struct_def_ = field->nested_flatbuffer;
+    nested_parser.enums_ = enums_;
+    nested_parser.opts = opts;
+    nested_parser.uses_flexbuffers_ = uses_flexbuffers_;
+
+    // Parse JSON substring into new flatbuffer builder using nested_parser
+    bool ok = nested_parser.Parse(substring.c_str(), nullptr, nullptr);
+
+    // Clean nested_parser to avoid deleting the elements in
+    // the SymbolTables on destruction
+    nested_parser.enums_.dict.clear();
+    nested_parser.enums_.vec.clear();
+
+    if (!ok) {
+      ECHECK(Error(nested_parser.error_));
+    }
+    // Force alignment for nested flatbuffer
+    builder_.ForceVectorAlignment(nested_parser.builder_.GetSize(), sizeof(uint8_t),
+                                  nested_parser.builder_.GetBufferMinAlignment());
+
+    auto off = builder_.CreateVector(nested_parser.builder_.GetBufferPointer(),
+                                     nested_parser.builder_.GetSize());
+    val.constant = NumToString(off.o);
+  }
+  return NoError();
+}
+
+CheckedError Parser::ParseMetaData(SymbolTable<Value> *attributes) {
+  if (Is('(')) {
+    NEXT();
+    for (;;) {
+      auto name = attribute_;
+      if (false == (Is(kTokenIdentifier) || Is(kTokenStringConstant)))
+        return Error("attribute name must be either identifier or string: " +
+          name);
+      if (known_attributes_.find(name) == known_attributes_.end())
+        return Error("user define attributes must be declared before use: " +
+                     name);
+      NEXT();
+      auto e = new Value();
+      attributes->Add(name, e);
+      if (Is(':')) {
+        NEXT();
+        ECHECK(ParseSingleValue(&name, *e, true));
+      }
+      if (Is(')')) {
+        NEXT();
+        break;
+      }
+      EXPECT(',');
+    }
+  }
+  return NoError();
+}
+
+CheckedError Parser::TryTypedValue(const std::string *name, int dtoken,
+                                   bool check, Value &e, BaseType req,
+                                   bool *destmatch) {
+  bool match = dtoken == token_;
+  if (match) {
+    FLATBUFFERS_ASSERT(*destmatch == false);
+    *destmatch = true;
+    e.constant = attribute_;
+    // Check token match
+    if (!check) {
+      if (e.type.base_type == BASE_TYPE_NONE) {
+        e.type.base_type = req;
+      } else {
+        return Error(
+            std::string("type mismatch: expecting: ") +
+            kTypeNames[e.type.base_type] + ", found: " + kTypeNames[req] +
+            ", name: " + (name ? *name : "") + ", value: " + e.constant);
+      }
+    }
+    // The exponent suffix of hexadecimal float-point number is mandatory.
+    // A hex-integer constant is forbidden as an initializer of float number.
+    if ((kTokenFloatConstant != dtoken) && IsFloat(e.type.base_type)) {
+      const auto &s = e.constant;
+      const auto k = s.find_first_of("0123456789.");
+      if ((std::string::npos != k) && (s.length() > (k + 1)) &&
+          (s[k] == '0' && is_alpha_char(s[k + 1], 'X')) &&
+          (std::string::npos == s.find_first_of("pP", k + 2))) {
+        return Error(
+            "invalid number, the exponent suffix of hexadecimal "
+            "floating-point literals is mandatory: \"" +
+            s + "\"");
+      }
+    }
+
+    NEXT();
+  }
+  return NoError();
+}
+
+CheckedError Parser::ParseEnumFromString(const Type &type,
+                                         std::string *result) {
+  const auto base_type =
+      type.enum_def ? type.enum_def->underlying_type.base_type : type.base_type;
+  if (!IsInteger(base_type)) return Error("not a valid value for this field");
+  uint64_t u64 = 0;
+  for (size_t pos = 0; pos != std::string::npos;) {
+    const auto delim = attribute_.find_first_of(' ', pos);
+    const auto last = (std::string::npos == delim);
+    auto word = attribute_.substr(pos, !last ? delim - pos : std::string::npos);
+    pos = !last ? delim + 1 : std::string::npos;
+    const EnumVal *ev = nullptr;
+    if (type.enum_def) {
+      ev = type.enum_def->Lookup(word);
+    } else {
+      auto dot = word.find_first_of('.');
+      if (std::string::npos == dot)
+        return Error("enum values need to be qualified by an enum type");
+      auto enum_def_str = word.substr(0, dot);
+      const auto enum_def = LookupEnum(enum_def_str);
+      if (!enum_def) return Error("unknown enum: " + enum_def_str);
+      auto enum_val_str = word.substr(dot + 1);
+      ev = enum_def->Lookup(enum_val_str);
+    }
+    if (!ev) return Error("unknown enum value: " + word);
+    u64 |= ev->GetAsUInt64();
+  }
+  *result = IsUnsigned(base_type) ? NumToString(u64)
+                                  : NumToString(static_cast<int64_t>(u64));
+  return NoError();
+}
+
+CheckedError Parser::ParseHash(Value &e, FieldDef *field) {
+  FLATBUFFERS_ASSERT(field);
+  Value *hash_name = field->attributes.Lookup("hash");
+  switch (e.type.base_type) {
+    case BASE_TYPE_SHORT: {
+      auto hash = FindHashFunction16(hash_name->constant.c_str());
+      int16_t hashed_value = static_cast<int16_t>(hash(attribute_.c_str()));
+      e.constant = NumToString(hashed_value);
+      break;
+    }
+    case BASE_TYPE_USHORT: {
+      auto hash = FindHashFunction16(hash_name->constant.c_str());
+      uint16_t hashed_value = hash(attribute_.c_str());
+      e.constant = NumToString(hashed_value);
+      break;
+    }
+    case BASE_TYPE_INT: {
+      auto hash = FindHashFunction32(hash_name->constant.c_str());
+      int32_t hashed_value = static_cast<int32_t>(hash(attribute_.c_str()));
+      e.constant = NumToString(hashed_value);
+      break;
+    }
+    case BASE_TYPE_UINT: {
+      auto hash = FindHashFunction32(hash_name->constant.c_str());
+      uint32_t hashed_value = hash(attribute_.c_str());
+      e.constant = NumToString(hashed_value);
+      break;
+    }
+    case BASE_TYPE_LONG: {
+      auto hash = FindHashFunction64(hash_name->constant.c_str());
+      int64_t hashed_value = static_cast<int64_t>(hash(attribute_.c_str()));
+      e.constant = NumToString(hashed_value);
+      break;
+    }
+    case BASE_TYPE_ULONG: {
+      auto hash = FindHashFunction64(hash_name->constant.c_str());
+      uint64_t hashed_value = hash(attribute_.c_str());
+      e.constant = NumToString(hashed_value);
+      break;
+    }
+    default: FLATBUFFERS_ASSERT(0);
+  }
+  NEXT();
+  return NoError();
+}
+
+CheckedError Parser::TokenError() {
+  return Error("cannot parse value starting with: " + TokenToStringId(token_));
+}
+
+// Re-pack helper (ParseSingleValue) to normalize defaults of scalars.
+template<typename T> inline void SingleValueRepack(Value &e, T val) {
+  // Remove leading zeros.
+  if (IsInteger(e.type.base_type)) { e.constant = NumToString(val); }
+}
+#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
+// Normilaze defaults NaN to unsigned quiet-NaN(0).
+static inline void SingleValueRepack(Value& e, float val) {
+  if (val != val) e.constant = "nan";
+}
+static inline void SingleValueRepack(Value& e, double val) {
+  if (val != val) e.constant = "nan";
+}
+#endif
+
+CheckedError Parser::ParseSingleValue(const std::string *name, Value &e,
+                                      bool check_now) {
+  // First see if this could be a conversion function:
+  if (token_ == kTokenIdentifier && *cursor_ == '(') {
+    // todo: Extract processing of conversion functions to ParseFunction.
+    const auto functionname = attribute_;
+    if (!IsFloat(e.type.base_type)) {
+      return Error(functionname + ": type of argument mismatch, expecting: " +
+                   kTypeNames[BASE_TYPE_DOUBLE] +
+                   ", found: " + kTypeNames[e.type.base_type] +
+                   ", name: " + (name ? *name : "") + ", value: " + e.constant);
+    }
+    NEXT();
+    EXPECT('(');
+    ECHECK(Recurse([&]() { return ParseSingleValue(name, e, false); }));
+    EXPECT(')');
+    // calculate with double precision
+    double x, y = 0.0;
+    ECHECK(atot(e.constant.c_str(), *this, &x));
+    auto func_match = false;
+    // clang-format off
+    #define FLATBUFFERS_FN_DOUBLE(name, op) \
+      if (!func_match && functionname == name) { y = op; func_match = true; }
+    FLATBUFFERS_FN_DOUBLE("deg", x / kPi * 180);
+    FLATBUFFERS_FN_DOUBLE("rad", x * kPi / 180);
+    FLATBUFFERS_FN_DOUBLE("sin", sin(x));
+    FLATBUFFERS_FN_DOUBLE("cos", cos(x));
+    FLATBUFFERS_FN_DOUBLE("tan", tan(x));
+    FLATBUFFERS_FN_DOUBLE("asin", asin(x));
+    FLATBUFFERS_FN_DOUBLE("acos", acos(x));
+    FLATBUFFERS_FN_DOUBLE("atan", atan(x));
+    // TODO(wvo): add more useful conversion functions here.
+    #undef FLATBUFFERS_FN_DOUBLE
+    // clang-format on
+    if (true != func_match) {
+      return Error(std::string("Unknown conversion function: ") + functionname +
+                   ", field name: " + (name ? *name : "") +
+                   ", value: " + e.constant);
+    }
+    e.constant = NumToString(y);
+    return NoError();
+  }
+
+  auto match = false;
+  const auto in_type = e.type.base_type;
+  // clang-format off
+  #define IF_ECHECK_(force, dtoken, check, req)    \
+    if (!match && ((check) || IsConstTrue(force))) \
+    ECHECK(TryTypedValue(name, dtoken, check, e, req, &match))
+  #define TRY_ECHECK(dtoken, check, req) IF_ECHECK_(false, dtoken, check, req)
+  #define FORCE_ECHECK(dtoken, check, req) IF_ECHECK_(true, dtoken, check, req)
+  // clang-format on
+
+  if (token_ == kTokenStringConstant || token_ == kTokenIdentifier) {
+    const auto kTokenStringOrIdent = token_;
+    // The string type is a most probable type, check it first.
+    TRY_ECHECK(kTokenStringConstant, in_type == BASE_TYPE_STRING,
+               BASE_TYPE_STRING);
+
+    // avoid escaped and non-ascii in the string
+    if (!match && (token_ == kTokenStringConstant) && IsScalar(in_type) &&
+        !attr_is_trivial_ascii_string_) {
+      return Error(
+          std::string("type mismatch or invalid value, an initializer of "
+                      "non-string field must be trivial ASCII string: type: ") +
+          kTypeNames[in_type] + ", name: " + (name ? *name : "") +
+          ", value: " + attribute_);
+    }
+
+    // A boolean as true/false. Boolean as Integer check below.
+    if (!match && IsBool(in_type)) {
+      auto is_true = attribute_ == "true";
+      if (is_true || attribute_ == "false") {
+        attribute_ = is_true ? "1" : "0";
+        // accepts both kTokenStringConstant and kTokenIdentifier
+        TRY_ECHECK(kTokenStringOrIdent, IsBool(in_type), BASE_TYPE_BOOL);
+      }
+    }
+    // Check if this could be a string/identifier enum value.
+    // Enum can have only true integer base type.
+    if (!match && IsInteger(in_type) && !IsBool(in_type) &&
+        IsIdentifierStart(*attribute_.c_str())) {
+      ECHECK(ParseEnumFromString(e.type, &e.constant));
+      NEXT();
+      match = true;
+    }
+    // Parse a float/integer number from the string.
+    if (!match) check_now = true;  // Re-pack if parsed from string literal.
+    if (!match && (token_ == kTokenStringConstant) && IsScalar(in_type)) {
+      // remove trailing whitespaces from attribute_
+      auto last = attribute_.find_last_not_of(' ');
+      if (std::string::npos != last)  // has non-whitespace
+        attribute_.resize(last + 1);
+    }
+    // Float numbers or nan, inf, pi, etc.
+    TRY_ECHECK(kTokenStringOrIdent, IsFloat(in_type), BASE_TYPE_FLOAT);
+    // An integer constant in string.
+    TRY_ECHECK(kTokenStringOrIdent, IsInteger(in_type), BASE_TYPE_INT);
+    // Unknown tokens will be interpreted as string type.
+    // An attribute value may be a scalar or string constant.
+    FORCE_ECHECK(kTokenStringConstant, in_type == BASE_TYPE_STRING,
+                 BASE_TYPE_STRING);
+  } else {
+    // Try a float number.
+    TRY_ECHECK(kTokenFloatConstant, IsFloat(in_type), BASE_TYPE_FLOAT);
+    // Integer token can init any scalar (integer of float).
+    FORCE_ECHECK(kTokenIntegerConstant, IsScalar(in_type), BASE_TYPE_INT);
+  }
+#undef FORCE_ECHECK
+#undef TRY_ECHECK
+#undef IF_ECHECK_
+
+  if (!match) {
+    std::string msg;
+    msg += "Cannot assign token starting with '" + TokenToStringId(token_) +
+           "' to value of <" + std::string(kTypeNames[in_type]) + "> type.";
+    return Error(msg);
+  }
+  const auto match_type = e.type.base_type; // may differ from in_type
+  // The check_now flag must be true when parse a fbs-schema.
+  // This flag forces to check default scalar values or metadata of field.
+  // For JSON parser the flag should be false.
+  // If it is set for JSON each value will be checked twice (see ParseTable).
+  if (check_now && IsScalar(match_type)) {
+    // clang-format off
+    switch (match_type) {
+    #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+            CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
+            case BASE_TYPE_ ## ENUM: {\
+                CTYPE val; \
+                ECHECK(atot(e.constant.c_str(), *this, &val)); \
+                SingleValueRepack(e, val); \
+              break; }
+    FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD);
+    #undef FLATBUFFERS_TD
+    default: break;
+    }
+    // clang-format on
+  }
+  return NoError();
+}
+
+StructDef *Parser::LookupCreateStruct(const std::string &name,
+                                      bool create_if_new, bool definition) {
+  std::string qualified_name = current_namespace_->GetFullyQualifiedName(name);
+  // See if it exists pre-declared by an unqualified use.
+  auto struct_def = LookupStruct(name);
+  if (struct_def && struct_def->predecl) {
+    if (definition) {
+      // Make sure it has the current namespace, and is registered under its
+      // qualified name.
+      struct_def->defined_namespace = current_namespace_;
+      structs_.Move(name, qualified_name);
+    }
+    return struct_def;
+  }
+  // See if it exists pre-declared by an qualified use.
+  struct_def = LookupStruct(qualified_name);
+  if (struct_def && struct_def->predecl) {
+    if (definition) {
+      // Make sure it has the current namespace.
+      struct_def->defined_namespace = current_namespace_;
+    }
+    return struct_def;
+  }
+  if (!definition) {
+    // Search thru parent namespaces.
+    for (size_t components = current_namespace_->components.size();
+         components && !struct_def; components--) {
+      struct_def = LookupStruct(
+          current_namespace_->GetFullyQualifiedName(name, components - 1));
+    }
+  }
+  if (!struct_def && create_if_new) {
+    struct_def = new StructDef();
+    if (definition) {
+      structs_.Add(qualified_name, struct_def);
+      struct_def->name = name;
+      struct_def->defined_namespace = current_namespace_;
+    } else {
+      // Not a definition.
+      // Rather than failing, we create a "pre declared" StructDef, due to
+      // circular references, and check for errors at the end of parsing.
+      // It is defined in the current namespace, as the best guess what the
+      // final namespace will be.
+      structs_.Add(name, struct_def);
+      struct_def->name = name;
+      struct_def->defined_namespace = current_namespace_;
+      struct_def->original_location.reset(
+          new std::string(file_being_parsed_ + ":" + NumToString(line_)));
+    }
+  }
+  return struct_def;
+}
+
+const EnumVal *EnumDef::MinValue() const {
+  return vals.vec.empty() ? nullptr : vals.vec.front();
+}
+const EnumVal *EnumDef::MaxValue() const {
+  return vals.vec.empty() ? nullptr : vals.vec.back();
+}
+
+template<typename T> static uint64_t EnumDistanceImpl(T e1, T e2) {
+  if (e1 < e2) { std::swap(e1, e2); }  // use std for scalars
+  // Signed overflow may occur, use unsigned calculation.
+  // The unsigned overflow is well-defined by C++ standard (modulo 2^n).
+  return static_cast<uint64_t>(e1) - static_cast<uint64_t>(e2);
+}
+
+uint64_t EnumDef::Distance(const EnumVal *v1, const EnumVal *v2) const {
+  return IsUInt64() ? EnumDistanceImpl(v1->GetAsUInt64(), v2->GetAsUInt64())
+                    : EnumDistanceImpl(v1->GetAsInt64(), v2->GetAsInt64());
+}
+
+std::string EnumDef::AllFlags() const {
+  FLATBUFFERS_ASSERT(attributes.Lookup("bit_flags"));
+  uint64_t u64 = 0;
+  for (auto it = Vals().begin(); it != Vals().end(); ++it) {
+    u64 |= (*it)->GetAsUInt64();
+  }
+  return IsUInt64() ? NumToString(u64) : NumToString(static_cast<int64_t>(u64));
+}
+
+EnumVal *EnumDef::ReverseLookup(int64_t enum_idx,
+                                bool skip_union_default) const {
+  auto skip_first = static_cast<int>(is_union && skip_union_default);
+  for (auto it = Vals().begin() + skip_first; it != Vals().end(); ++it) {
+    if ((*it)->GetAsInt64() == enum_idx) { return *it; }
+  }
+  return nullptr;
+}
+
+EnumVal *EnumDef::FindByValue(const std::string &constant) const {
+  int64_t i64;
+  auto done = false;
+  if (IsUInt64()) {
+    uint64_t u64;  // avoid reinterpret_cast of pointers
+    done = StringToNumber(constant.c_str(), &u64);
+    i64 = static_cast<int64_t>(u64);
+  } else {
+    done = StringToNumber(constant.c_str(), &i64);
+  }
+  FLATBUFFERS_ASSERT(done);
+  if (!done) return nullptr;
+  return ReverseLookup(i64, false);
+}
+
+void EnumDef::SortByValue() {
+  auto &v = vals.vec;
+  if (IsUInt64())
+    std::sort(v.begin(), v.end(), [](const EnumVal *e1, const EnumVal *e2) {
+      return e1->GetAsUInt64() < e2->GetAsUInt64();
+    });
+  else
+    std::sort(v.begin(), v.end(), [](const EnumVal *e1, const EnumVal *e2) {
+      return e1->GetAsInt64() < e2->GetAsInt64();
+    });
+}
+
+void EnumDef::RemoveDuplicates() {
+  // This method depends form SymbolTable implementation!
+  // 1) vals.vec - owner (raw pointer)
+  // 2) vals.dict - access map
+  auto first = vals.vec.begin();
+  auto last = vals.vec.end();
+  if (first == last) return;
+  auto result = first;
+  while (++first != last) {
+    if ((*result)->value != (*first)->value) {
+      *(++result) = *first;
+    } else {
+      auto ev = *first;
+      for (auto it = vals.dict.begin(); it != vals.dict.end(); ++it) {
+        if (it->second == ev) it->second = *result;  // reassign
+      }
+      delete ev;  // delete enum value
+      *first = nullptr;
+    }
+  }
+  vals.vec.erase(++result, last);
+}
+
+template<typename T> void EnumDef::ChangeEnumValue(EnumVal *ev, T new_value) {
+  ev->value = static_cast<int64_t>(new_value);
+}
+
+namespace EnumHelper {
+template<BaseType E> struct EnumValType { typedef int64_t type; };
+template<> struct EnumValType<BASE_TYPE_ULONG> { typedef uint64_t type; };
+}  // namespace EnumHelper
+
+struct EnumValBuilder {
+  EnumVal *CreateEnumerator(const std::string &ev_name) {
+    FLATBUFFERS_ASSERT(!temp);
+    auto first = enum_def.vals.vec.empty();
+    user_value = first;
+    temp = new EnumVal(ev_name, first ? 0 : enum_def.vals.vec.back()->value);
+    return temp;
+  }
+
+  EnumVal *CreateEnumerator(const std::string &ev_name, int64_t val) {
+    FLATBUFFERS_ASSERT(!temp);
+    user_value = true;
+    temp = new EnumVal(ev_name, val);
+    return temp;
+  }
+
+  FLATBUFFERS_CHECKED_ERROR AcceptEnumerator(const std::string &name) {
+    FLATBUFFERS_ASSERT(temp);
+    ECHECK(ValidateValue(&temp->value, false == user_value));
+    FLATBUFFERS_ASSERT((temp->union_type.enum_def == nullptr) ||
+                       (temp->union_type.enum_def == &enum_def));
+    auto not_unique = enum_def.vals.Add(name, temp);
+    temp = nullptr;
+    if (not_unique) return parser.Error("enum value already exists: " + name);
+    return NoError();
+  }
+
+  FLATBUFFERS_CHECKED_ERROR AcceptEnumerator() {
+    return AcceptEnumerator(temp->name);
+  }
+
+  FLATBUFFERS_CHECKED_ERROR AssignEnumeratorValue(const std::string &value) {
+    user_value = true;
+    auto fit = false;
+    auto ascending = false;
+    if (enum_def.IsUInt64()) {
+      uint64_t u64;
+      fit = StringToNumber(value.c_str(), &u64);
+      ascending = u64 > temp->GetAsUInt64();
+      temp->value = static_cast<int64_t>(u64);  // well-defined since C++20.
+    } else {
+      int64_t i64;
+      fit = StringToNumber(value.c_str(), &i64);
+      ascending = i64 > temp->GetAsInt64();
+      temp->value = i64;
+    }
+    if (!fit) return parser.Error("enum value does not fit, \"" + value + "\"");
+    if (!ascending && strict_ascending && !enum_def.vals.vec.empty())
+      return parser.Error("enum values must be specified in ascending order");
+    return NoError();
+  }
+
+  template<BaseType E, typename CTYPE>
+  inline FLATBUFFERS_CHECKED_ERROR ValidateImpl(int64_t *ev, int m) {
+    typedef typename EnumHelper::EnumValType<E>::type T;  // int64_t or uint64_t
+    static_assert(sizeof(T) == sizeof(int64_t), "invalid EnumValType");
+    const auto v = static_cast<T>(*ev);
+    auto up = static_cast<T>((flatbuffers::numeric_limits<CTYPE>::max)());
+    auto dn = static_cast<T>((flatbuffers::numeric_limits<CTYPE>::lowest)());
+    if (v < dn || v > (up - m)) {
+      return parser.Error("enum value does not fit, \"" + NumToString(v) +
+                          (m ? " + 1\"" : "\"") + " out of " +
+                          TypeToIntervalString<CTYPE>());
+    }
+    *ev = static_cast<int64_t>(v + m);  // well-defined since C++20.
+    return NoError();
+  }
+
+  FLATBUFFERS_CHECKED_ERROR ValidateValue(int64_t *ev, bool next) {
+    // clang-format off
+    switch (enum_def.underlying_type.base_type) {
+    #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE,   \
+                           PTYPE, RTYPE, KTYPE)                         \
+      case BASE_TYPE_##ENUM: {                                          \
+        if (!IsInteger(BASE_TYPE_##ENUM)) break;                        \
+        return ValidateImpl<BASE_TYPE_##ENUM, CTYPE>(ev, next ? 1 : 0); \
+      }
+      FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD);
+    #undef FLATBUFFERS_TD
+    default: break;
+    }
+    // clang-format on
+    return parser.Error("fatal: invalid enum underlying type");
+  }
+
+  EnumValBuilder(Parser &_parser, EnumDef &_enum_def, bool strict_order = true)
+      : parser(_parser),
+        enum_def(_enum_def),
+        temp(nullptr),
+        strict_ascending(strict_order),
+        user_value(false) {}
+
+  ~EnumValBuilder() { delete temp; }
+
+  Parser &parser;
+  EnumDef &enum_def;
+  EnumVal *temp;
+  const bool strict_ascending;
+  bool user_value;
+};
+
+CheckedError Parser::ParseEnum(const bool is_union, EnumDef **dest) {
+  std::vector<std::string> enum_comment = doc_comment_;
+  NEXT();
+  std::string enum_name = attribute_;
+  EXPECT(kTokenIdentifier);
+  EnumDef *enum_def;
+  ECHECK(StartEnum(enum_name, is_union, &enum_def));
+  enum_def->doc_comment = enum_comment;
+  if (!is_union && !opts.proto_mode) {
+    // Give specialized error message, since this type spec used to
+    // be optional in the first FlatBuffers release.
+    if (!Is(':')) {
+      return Error(
+          "must specify the underlying integer type for this"
+          " enum (e.g. \': short\', which was the default).");
+    } else {
+      NEXT();
+    }
+    // Specify the integer type underlying this enum.
+    ECHECK(ParseType(enum_def->underlying_type));
+    if (!IsInteger(enum_def->underlying_type.base_type) ||
+        IsBool(enum_def->underlying_type.base_type))
+      return Error("underlying enum type must be integral");
+    // Make this type refer back to the enum it was derived from.
+    enum_def->underlying_type.enum_def = enum_def;
+  }
+  ECHECK(ParseMetaData(&enum_def->attributes));
+  const auto underlying_type = enum_def->underlying_type.base_type;
+  if (enum_def->attributes.Lookup("bit_flags") &&
+      !IsUnsigned(underlying_type)) {
+    // todo: Convert to the Error in the future?
+    Warning("underlying type of bit_flags enum must be unsigned");
+  }
+  // Protobuf allows them to be specified in any order, so sort afterwards.
+  const auto strict_ascending = (false == opts.proto_mode);
+  EnumValBuilder evb(*this, *enum_def, strict_ascending);
+  EXPECT('{');
+  // A lot of code generatos expect that an enum is not-empty.
+  if ((is_union || Is('}')) && !opts.proto_mode) {
+    evb.CreateEnumerator("NONE");
+    ECHECK(evb.AcceptEnumerator());
+  }
+  std::set<std::pair<BaseType, StructDef *>> union_types;
+  while (!Is('}')) {
+    if (opts.proto_mode && attribute_ == "option") {
+      ECHECK(ParseProtoOption());
+    } else {
+      auto &ev = *evb.CreateEnumerator(attribute_);
+      auto full_name = ev.name;
+      ev.doc_comment = doc_comment_;
+      EXPECT(kTokenIdentifier);
+      if (is_union) {
+        ECHECK(ParseNamespacing(&full_name, &ev.name));
+        if (opts.union_value_namespacing) {
+          // Since we can't namespace the actual enum identifiers, turn
+          // namespace parts into part of the identifier.
+          ev.name = full_name;
+          std::replace(ev.name.begin(), ev.name.end(), '.', '_');
+        }
+        if (Is(':')) {
+          NEXT();
+          ECHECK(ParseType(ev.union_type));
+          if (ev.union_type.base_type != BASE_TYPE_STRUCT &&
+              ev.union_type.base_type != BASE_TYPE_STRING)
+            return Error("union value type may only be table/struct/string");
+        } else {
+          ev.union_type = Type(BASE_TYPE_STRUCT, LookupCreateStruct(full_name));
+        }
+        if (!enum_def->uses_multiple_type_instances) {
+          auto ins = union_types.insert(std::make_pair(
+              ev.union_type.base_type, ev.union_type.struct_def));
+          enum_def->uses_multiple_type_instances = (false == ins.second);
+        }
+      }
+
+      if (Is('=')) {
+        NEXT();
+        ECHECK(evb.AssignEnumeratorValue(attribute_));
+        EXPECT(kTokenIntegerConstant);
+      } else if (false == strict_ascending) {
+        // The opts.proto_mode flag is active.
+        return Error("Protobuf mode doesn't allow implicit enum values.");
+      }
+
+      ECHECK(evb.AcceptEnumerator());
+
+      if (opts.proto_mode && Is('[')) {
+        NEXT();
+        // ignore attributes on enums.
+        while (token_ != ']') NEXT();
+        NEXT();
+      }
+    }
+    if (!Is(opts.proto_mode ? ';' : ',')) break;
+    NEXT();
+  }
+  EXPECT('}');
+
+  // At this point, the enum can be empty if input is invalid proto-file.
+  if (!enum_def->size())
+    return Error("incomplete enum declaration, values not found");
+
+  if (enum_def->attributes.Lookup("bit_flags")) {
+    const auto base_width = static_cast<uint64_t>(8 * SizeOf(underlying_type));
+    for (auto it = enum_def->Vals().begin(); it != enum_def->Vals().end();
+         ++it) {
+      auto ev = *it;
+      const auto u = ev->GetAsUInt64();
+      // Stop manipulations with the sign.
+      if (!IsUnsigned(underlying_type) && u == (base_width - 1))
+        return Error("underlying type of bit_flags enum must be unsigned");
+      if (u >= base_width)
+        return Error("bit flag out of range of underlying integral type");
+      enum_def->ChangeEnumValue(ev, 1ULL << u);
+    }
+  }
+
+  if (false == strict_ascending)
+    enum_def->SortByValue();  // Must be sorted to use MinValue/MaxValue.
+
+  if (dest) *dest = enum_def;
+  types_.Add(current_namespace_->GetFullyQualifiedName(enum_def->name),
+             new Type(BASE_TYPE_UNION, nullptr, enum_def));
+  return NoError();
+}
+
+CheckedError Parser::StartStruct(const std::string &name, StructDef **dest) {
+  auto &struct_def = *LookupCreateStruct(name, true, true);
+  if (!struct_def.predecl) return Error("datatype already exists: " + name);
+  struct_def.predecl = false;
+  struct_def.name = name;
+  struct_def.file = file_being_parsed_;
+  // Move this struct to the back of the vector just in case it was predeclared,
+  // to preserve declaration order.
+  *std::remove(structs_.vec.begin(), structs_.vec.end(), &struct_def) =
+      &struct_def;
+  *dest = &struct_def;
+  return NoError();
+}
+
+CheckedError Parser::CheckClash(std::vector<FieldDef *> &fields,
+                                StructDef *struct_def, const char *suffix,
+                                BaseType basetype) {
+  auto len = strlen(suffix);
+  for (auto it = fields.begin(); it != fields.end(); ++it) {
+    auto &fname = (*it)->name;
+    if (fname.length() > len &&
+        fname.compare(fname.length() - len, len, suffix) == 0 &&
+        (*it)->value.type.base_type != BASE_TYPE_UTYPE) {
+      auto field =
+          struct_def->fields.Lookup(fname.substr(0, fname.length() - len));
+      if (field && field->value.type.base_type == basetype)
+        return Error("Field " + fname +
+                     " would clash with generated functions for field " +
+                     field->name);
+    }
+  }
+  return NoError();
+}
+
+bool Parser::SupportsAdvancedUnionFeatures() const {
+  return opts.lang_to_generate != 0 &&
+         (opts.lang_to_generate & ~(IDLOptions::kCpp | IDLOptions::kJs |
+                                    IDLOptions::kTs | IDLOptions::kPhp |
+                                    IDLOptions::kJava | IDLOptions::kCSharp |
+                                    IDLOptions::kKotlin |
+                                    IDLOptions::kBinary)) == 0;
+}
+
+bool Parser::SupportsAdvancedArrayFeatures() const {
+  return (opts.lang_to_generate &
+          ~(IDLOptions::kCpp | IDLOptions::kPython | IDLOptions::kJava |
+            IDLOptions::kCSharp | IDLOptions::kJsonSchema | IDLOptions::kJson |
+            IDLOptions::kBinary)) == 0;
+}
+
+Namespace *Parser::UniqueNamespace(Namespace *ns) {
+  for (auto it = namespaces_.begin(); it != namespaces_.end(); ++it) {
+    if (ns->components == (*it)->components) {
+      delete ns;
+      return *it;
+    }
+  }
+  namespaces_.push_back(ns);
+  return ns;
+}
+
+std::string Parser::UnqualifiedName(const std::string &full_qualified_name) {
+  Namespace *ns = new Namespace();
+
+  std::size_t current, previous = 0;
+  current = full_qualified_name.find('.');
+  while (current != std::string::npos) {
+    ns->components.push_back(
+        full_qualified_name.substr(previous, current - previous));
+    previous = current + 1;
+    current = full_qualified_name.find('.', previous);
+  }
+  current_namespace_ = UniqueNamespace(ns);
+  return full_qualified_name.substr(previous, current - previous);
+}
+
+static bool compareFieldDefs(const FieldDef *a, const FieldDef *b) {
+  auto a_id = atoi(a->attributes.Lookup("id")->constant.c_str());
+  auto b_id = atoi(b->attributes.Lookup("id")->constant.c_str());
+  return a_id < b_id;
+}
+
+CheckedError Parser::ParseDecl() {
+  std::vector<std::string> dc = doc_comment_;
+  bool fixed = IsIdent("struct");
+  if (!fixed && !IsIdent("table")) return Error("declaration expected");
+  NEXT();
+  std::string name = attribute_;
+  EXPECT(kTokenIdentifier);
+  StructDef *struct_def;
+  ECHECK(StartStruct(name, &struct_def));
+  struct_def->doc_comment = dc;
+  struct_def->fixed = fixed;
+  ECHECK(ParseMetaData(&struct_def->attributes));
+  struct_def->sortbysize =
+      struct_def->attributes.Lookup("original_order") == nullptr && !fixed;
+  EXPECT('{');
+  while (token_ != '}') ECHECK(ParseField(*struct_def));
+  auto force_align = struct_def->attributes.Lookup("force_align");
+  if (fixed) {
+    if (force_align) {
+      auto align = static_cast<size_t>(atoi(force_align->constant.c_str()));
+      if (force_align->type.base_type != BASE_TYPE_INT ||
+          align < struct_def->minalign || align > FLATBUFFERS_MAX_ALIGNMENT ||
+          align & (align - 1))
+        return Error(
+            "force_align must be a power of two integer ranging from the"
+            "struct\'s natural alignment to " +
+            NumToString(FLATBUFFERS_MAX_ALIGNMENT));
+      struct_def->minalign = align;
+    }
+    if (!struct_def->bytesize) return Error("size 0 structs not allowed");
+  }
+  struct_def->PadLastField(struct_def->minalign);
+  // Check if this is a table that has manual id assignments
+  auto &fields = struct_def->fields.vec;
+  if (!fixed && fields.size()) {
+    size_t num_id_fields = 0;
+    for (auto it = fields.begin(); it != fields.end(); ++it) {
+      if ((*it)->attributes.Lookup("id")) num_id_fields++;
+    }
+    // If any fields have ids..
+    if (num_id_fields) {
+      // Then all fields must have them.
+      if (num_id_fields != fields.size())
+        return Error(
+            "either all fields or no fields must have an 'id' attribute");
+      // Simply sort by id, then the fields are the same as if no ids had
+      // been specified.
+      std::sort(fields.begin(), fields.end(), compareFieldDefs);
+      // Verify we have a contiguous set, and reassign vtable offsets.
+      for (int i = 0; i < static_cast<int>(fields.size()); i++) {
+        if (i != atoi(fields[i]->attributes.Lookup("id")->constant.c_str()))
+          return Error("field id\'s must be consecutive from 0, id " +
+                       NumToString(i) + " missing or set twice");
+        fields[i]->value.offset = FieldIndexToOffset(static_cast<voffset_t>(i));
+      }
+    }
+  }
+
+  ECHECK(
+      CheckClash(fields, struct_def, UnionTypeFieldSuffix(), BASE_TYPE_UNION));
+  ECHECK(CheckClash(fields, struct_def, "Type", BASE_TYPE_UNION));
+  ECHECK(CheckClash(fields, struct_def, "_length", BASE_TYPE_VECTOR));
+  ECHECK(CheckClash(fields, struct_def, "Length", BASE_TYPE_VECTOR));
+  ECHECK(CheckClash(fields, struct_def, "_byte_vector", BASE_TYPE_STRING));
+  ECHECK(CheckClash(fields, struct_def, "ByteVector", BASE_TYPE_STRING));
+  EXPECT('}');
+  types_.Add(current_namespace_->GetFullyQualifiedName(struct_def->name),
+             new Type(BASE_TYPE_STRUCT, struct_def, nullptr));
+  return NoError();
+}
+
+CheckedError Parser::ParseService() {
+  std::vector<std::string> service_comment = doc_comment_;
+  NEXT();
+  auto service_name = attribute_;
+  EXPECT(kTokenIdentifier);
+  auto &service_def = *new ServiceDef();
+  service_def.name = service_name;
+  service_def.file = file_being_parsed_;
+  service_def.doc_comment = service_comment;
+  service_def.defined_namespace = current_namespace_;
+  if (services_.Add(current_namespace_->GetFullyQualifiedName(service_name),
+                    &service_def))
+    return Error("service already exists: " + service_name);
+  ECHECK(ParseMetaData(&service_def.attributes));
+  EXPECT('{');
+  do {
+    std::vector<std::string> doc_comment = doc_comment_;
+    auto rpc_name = attribute_;
+    EXPECT(kTokenIdentifier);
+    EXPECT('(');
+    Type reqtype, resptype;
+    ECHECK(ParseTypeIdent(reqtype));
+    EXPECT(')');
+    EXPECT(':');
+    ECHECK(ParseTypeIdent(resptype));
+    if (reqtype.base_type != BASE_TYPE_STRUCT || reqtype.struct_def->fixed ||
+        resptype.base_type != BASE_TYPE_STRUCT || resptype.struct_def->fixed)
+      return Error("rpc request and response types must be tables");
+    auto &rpc = *new RPCCall();
+    rpc.name = rpc_name;
+    rpc.request = reqtype.struct_def;
+    rpc.response = resptype.struct_def;
+    rpc.doc_comment = doc_comment;
+    if (service_def.calls.Add(rpc_name, &rpc))
+      return Error("rpc already exists: " + rpc_name);
+    ECHECK(ParseMetaData(&rpc.attributes));
+    EXPECT(';');
+  } while (token_ != '}');
+  NEXT();
+  return NoError();
+}
+
+bool Parser::SetRootType(const char *name) {
+  root_struct_def_ = LookupStruct(name);
+  if (!root_struct_def_)
+    root_struct_def_ =
+        LookupStruct(current_namespace_->GetFullyQualifiedName(name));
+  return root_struct_def_ != nullptr;
+}
+
+void Parser::MarkGenerated() {
+  // This function marks all existing definitions as having already
+  // been generated, which signals no code for included files should be
+  // generated.
+  for (auto it = enums_.vec.begin(); it != enums_.vec.end(); ++it) {
+    (*it)->generated = true;
+  }
+  for (auto it = structs_.vec.begin(); it != structs_.vec.end(); ++it) {
+    if (!(*it)->predecl) { (*it)->generated = true; }
+  }
+  for (auto it = services_.vec.begin(); it != services_.vec.end(); ++it) {
+    (*it)->generated = true;
+  }
+}
+
+CheckedError Parser::ParseNamespace() {
+  NEXT();
+  auto ns = new Namespace();
+  namespaces_.push_back(ns);  // Store it here to not leak upon error.
+  if (token_ != ';') {
+    for (;;) {
+      ns->components.push_back(attribute_);
+      EXPECT(kTokenIdentifier);
+      if (Is('.')) NEXT() else break;
+    }
+  }
+  namespaces_.pop_back();
+  current_namespace_ = UniqueNamespace(ns);
+  EXPECT(';');
+  return NoError();
+}
+
+// Best effort parsing of .proto declarations, with the aim to turn them
+// in the closest corresponding FlatBuffer equivalent.
+// We parse everything as identifiers instead of keywords, since we don't
+// want protobuf keywords to become invalid identifiers in FlatBuffers.
+CheckedError Parser::ParseProtoDecl() {
+  bool isextend = IsIdent("extend");
+  if (IsIdent("package")) {
+    // These are identical in syntax to FlatBuffer's namespace decl.
+    ECHECK(ParseNamespace());
+  } else if (IsIdent("message") || isextend) {
+    std::vector<std::string> struct_comment = doc_comment_;
+    NEXT();
+    StructDef *struct_def = nullptr;
+    Namespace *parent_namespace = nullptr;
+    if (isextend) {
+      if (Is('.')) NEXT();  // qualified names may start with a . ?
+      auto id = attribute_;
+      EXPECT(kTokenIdentifier);
+      ECHECK(ParseNamespacing(&id, nullptr));
+      struct_def = LookupCreateStruct(id, false);
+      if (!struct_def)
+        return Error("cannot extend unknown message type: " + id);
+    } else {
+      std::string name = attribute_;
+      EXPECT(kTokenIdentifier);
+      ECHECK(StartStruct(name, &struct_def));
+      // Since message definitions can be nested, we create a new namespace.
+      auto ns = new Namespace();
+      // Copy of current namespace.
+      *ns = *current_namespace_;
+      // But with current message name.
+      ns->components.push_back(name);
+      ns->from_table++;
+      parent_namespace = current_namespace_;
+      current_namespace_ = UniqueNamespace(ns);
+    }
+    struct_def->doc_comment = struct_comment;
+    ECHECK(ParseProtoFields(struct_def, isextend, false));
+    if (!isextend) { current_namespace_ = parent_namespace; }
+    if (Is(';')) NEXT();
+  } else if (IsIdent("enum")) {
+    // These are almost the same, just with different terminator:
+    EnumDef *enum_def;
+    ECHECK(ParseEnum(false, &enum_def));
+    if (Is(';')) NEXT();
+    // Temp: remove any duplicates, as .fbs files can't handle them.
+    enum_def->RemoveDuplicates();
+  } else if (IsIdent("syntax")) {  // Skip these.
+    NEXT();
+    EXPECT('=');
+    EXPECT(kTokenStringConstant);
+    EXPECT(';');
+  } else if (IsIdent("option")) {  // Skip these.
+    ECHECK(ParseProtoOption());
+    EXPECT(';');
+  } else if (IsIdent("service")) {  // Skip these.
+    NEXT();
+    EXPECT(kTokenIdentifier);
+    ECHECK(ParseProtoCurliesOrIdent());
+  } else {
+    return Error("don\'t know how to parse .proto declaration starting with " +
+                 TokenToStringId(token_));
+  }
+  return NoError();
+}
+
+CheckedError Parser::StartEnum(const std::string &enum_name, bool is_union,
+                               EnumDef **dest) {
+  auto &enum_def = *new EnumDef();
+  enum_def.name = enum_name;
+  enum_def.file = file_being_parsed_;
+  enum_def.doc_comment = doc_comment_;
+  enum_def.is_union = is_union;
+  enum_def.defined_namespace = current_namespace_;
+  if (enums_.Add(current_namespace_->GetFullyQualifiedName(enum_name),
+                 &enum_def))
+    return Error("enum already exists: " + enum_name);
+  enum_def.underlying_type.base_type = is_union ? BASE_TYPE_UTYPE
+                                                : BASE_TYPE_INT;
+  enum_def.underlying_type.enum_def = &enum_def;
+  if (dest) *dest = &enum_def;
+  return NoError();
+}
+
+CheckedError Parser::ParseProtoFields(StructDef *struct_def, bool isextend,
+                                      bool inside_oneof) {
+  EXPECT('{');
+  while (token_ != '}') {
+    if (IsIdent("message") || IsIdent("extend") || IsIdent("enum")) {
+      // Nested declarations.
+      ECHECK(ParseProtoDecl());
+    } else if (IsIdent("extensions")) {  // Skip these.
+      NEXT();
+      EXPECT(kTokenIntegerConstant);
+      if (Is(kTokenIdentifier)) {
+        NEXT();  // to
+        NEXT();  // num
+      }
+      EXPECT(';');
+    } else if (IsIdent("option")) {  // Skip these.
+      ECHECK(ParseProtoOption());
+      EXPECT(';');
+    } else if (IsIdent("reserved")) {  // Skip these.
+      NEXT();
+      while (!Is(';')) { NEXT(); }  // A variety of formats, just skip.
+      NEXT();
+    } else {
+      std::vector<std::string> field_comment = doc_comment_;
+      // Parse the qualifier.
+      bool required = false;
+      bool repeated = false;
+      bool oneof = false;
+      if (!inside_oneof) {
+        if (IsIdent("optional")) {
+          // This is the default.
+          NEXT();
+        } else if (IsIdent("required")) {
+          required = true;
+          NEXT();
+        } else if (IsIdent("repeated")) {
+          repeated = true;
+          NEXT();
+        } else if (IsIdent("oneof")) {
+          oneof = true;
+          NEXT();
+        } else {
+          // can't error, proto3 allows decls without any of the above.
+        }
+      }
+      StructDef *anonymous_struct = nullptr;
+      EnumDef *oneof_union = nullptr;
+      Type type;
+      if (IsIdent("group") || oneof) {
+        if (!oneof) NEXT();
+        if (oneof && opts.proto_oneof_union) {
+          auto name = MakeCamel(attribute_, true) + "Union";
+          ECHECK(StartEnum(name, true, &oneof_union));
+          type = Type(BASE_TYPE_UNION, nullptr, oneof_union);
+        } else {
+          auto name = "Anonymous" + NumToString(anonymous_counter++);
+          ECHECK(StartStruct(name, &anonymous_struct));
+          type = Type(BASE_TYPE_STRUCT, anonymous_struct);
+        }
+      } else {
+        ECHECK(ParseTypeFromProtoType(&type));
+      }
+      // Repeated elements get mapped to a vector.
+      if (repeated) {
+        type.element = type.base_type;
+        type.base_type = BASE_TYPE_VECTOR;
+        if (type.element == BASE_TYPE_VECTOR) {
+          // We have a vector or vectors, which FlatBuffers doesn't support.
+          // For now make it a vector of string (since the source is likely
+          // "repeated bytes").
+          // TODO(wvo): A better solution would be to wrap this in a table.
+          type.element = BASE_TYPE_STRING;
+        }
+      }
+      std::string name = attribute_;
+      EXPECT(kTokenIdentifier);
+      if (!oneof) {
+        // Parse the field id. Since we're just translating schemas, not
+        // any kind of binary compatibility, we can safely ignore these, and
+        // assign our own.
+        EXPECT('=');
+        EXPECT(kTokenIntegerConstant);
+      }
+      FieldDef *field = nullptr;
+      if (isextend) {
+        // We allow a field to be re-defined when extending.
+        // TODO: are there situations where that is problematic?
+        field = struct_def->fields.Lookup(name);
+      }
+      if (!field) ECHECK(AddField(*struct_def, name, type, &field));
+      field->doc_comment = field_comment;
+      if (!IsScalar(type.base_type)) field->required = required;
+      // See if there's a default specified.
+      if (Is('[')) {
+        NEXT();
+        for (;;) {
+          auto key = attribute_;
+          ECHECK(ParseProtoKey());
+          EXPECT('=');
+          auto val = attribute_;
+          ECHECK(ParseProtoCurliesOrIdent());
+          if (key == "default") {
+            // Temp: skip non-numeric defaults (enums).
+            auto numeric = strpbrk(val.c_str(), "0123456789-+.");
+            if (IsScalar(type.base_type) && numeric == val.c_str())
+              field->value.constant = val;
+          } else if (key == "deprecated") {
+            field->deprecated = val == "true";
+          }
+          if (!Is(',')) break;
+          NEXT();
+        }
+        EXPECT(']');
+      }
+      if (anonymous_struct) {
+        ECHECK(ParseProtoFields(anonymous_struct, false, oneof));
+        if (Is(';')) NEXT();
+      } else if (oneof_union) {
+        // Parse into a temporary StructDef, then transfer fields into an
+        // EnumDef describing the oneof as a union.
+        StructDef oneof_struct;
+        ECHECK(ParseProtoFields(&oneof_struct, false, oneof));
+        if (Is(';')) NEXT();
+        for (auto field_it = oneof_struct.fields.vec.begin();
+             field_it != oneof_struct.fields.vec.end(); ++field_it) {
+          const auto &oneof_field = **field_it;
+          const auto &oneof_type = oneof_field.value.type;
+          if (oneof_type.base_type != BASE_TYPE_STRUCT ||
+              !oneof_type.struct_def || oneof_type.struct_def->fixed)
+            return Error("oneof '" + name +
+                "' cannot be mapped to a union because member '" +
+                oneof_field.name + "' is not a table type.");
+          EnumValBuilder evb(*this, *oneof_union);
+          auto ev = evb.CreateEnumerator(oneof_type.struct_def->name);
+          ev->union_type = oneof_type;
+          ev->doc_comment = oneof_field.doc_comment;
+          ECHECK(evb.AcceptEnumerator(oneof_field.name));
+        }
+      } else {
+        EXPECT(';');
+      }
+    }
+  }
+  NEXT();
+  return NoError();
+}
+
+CheckedError Parser::ParseProtoKey() {
+  if (token_ == '(') {
+    NEXT();
+    // Skip "(a.b)" style custom attributes.
+    while (token_ == '.' || token_ == kTokenIdentifier) NEXT();
+    EXPECT(')');
+    while (Is('.')) {
+      NEXT();
+      EXPECT(kTokenIdentifier);
+    }
+  } else {
+    EXPECT(kTokenIdentifier);
+  }
+  return NoError();
+}
+
+CheckedError Parser::ParseProtoCurliesOrIdent() {
+  if (Is('{')) {
+    NEXT();
+    for (int nesting = 1; nesting;) {
+      if (token_ == '{')
+        nesting++;
+      else if (token_ == '}')
+        nesting--;
+      NEXT();
+    }
+  } else {
+    NEXT();  // Any single token.
+  }
+  return NoError();
+}
+
+CheckedError Parser::ParseProtoOption() {
+  NEXT();
+  ECHECK(ParseProtoKey());
+  EXPECT('=');
+  ECHECK(ParseProtoCurliesOrIdent());
+  return NoError();
+}
+
+// Parse a protobuf type, and map it to the corresponding FlatBuffer one.
+CheckedError Parser::ParseTypeFromProtoType(Type *type) {
+  struct type_lookup {
+    const char *proto_type;
+    BaseType fb_type, element;
+  };
+  static type_lookup lookup[] = {
+    { "float", BASE_TYPE_FLOAT, BASE_TYPE_NONE },
+    { "double", BASE_TYPE_DOUBLE, BASE_TYPE_NONE },
+    { "int32", BASE_TYPE_INT, BASE_TYPE_NONE },
+    { "int64", BASE_TYPE_LONG, BASE_TYPE_NONE },
+    { "uint32", BASE_TYPE_UINT, BASE_TYPE_NONE },
+    { "uint64", BASE_TYPE_ULONG, BASE_TYPE_NONE },
+    { "sint32", BASE_TYPE_INT, BASE_TYPE_NONE },
+    { "sint64", BASE_TYPE_LONG, BASE_TYPE_NONE },
+    { "fixed32", BASE_TYPE_UINT, BASE_TYPE_NONE },
+    { "fixed64", BASE_TYPE_ULONG, BASE_TYPE_NONE },
+    { "sfixed32", BASE_TYPE_INT, BASE_TYPE_NONE },
+    { "sfixed64", BASE_TYPE_LONG, BASE_TYPE_NONE },
+    { "bool", BASE_TYPE_BOOL, BASE_TYPE_NONE },
+    { "string", BASE_TYPE_STRING, BASE_TYPE_NONE },
+    { "bytes", BASE_TYPE_VECTOR, BASE_TYPE_UCHAR },
+    { nullptr, BASE_TYPE_NONE, BASE_TYPE_NONE }
+  };
+  for (auto tl = lookup; tl->proto_type; tl++) {
+    if (attribute_ == tl->proto_type) {
+      type->base_type = tl->fb_type;
+      type->element = tl->element;
+      NEXT();
+      return NoError();
+    }
+  }
+  if (Is('.')) NEXT();  // qualified names may start with a . ?
+  ECHECK(ParseTypeIdent(*type));
+  return NoError();
+}
+
+CheckedError Parser::SkipAnyJsonValue() {
+  switch (token_) {
+    case '{': {
+      size_t fieldn_outer = 0;
+      return ParseTableDelimiters(
+          fieldn_outer, nullptr,
+          [&](const std::string &, size_t &fieldn,
+              const StructDef *) -> CheckedError {
+            ECHECK(Recurse([&]() { return SkipAnyJsonValue(); }));
+            fieldn++;
+            return NoError();
+          });
+    }
+    case '[': {
+      uoffset_t count = 0;
+      return ParseVectorDelimiters(count, [&](uoffset_t &) -> CheckedError {
+        return Recurse([&]() { return SkipAnyJsonValue(); });
+      });
+    }
+    case kTokenStringConstant:
+    case kTokenIntegerConstant:
+    case kTokenFloatConstant: NEXT(); break;
+    default:
+      if (IsIdent("true") || IsIdent("false") || IsIdent("null")) {
+        NEXT();
+      } else
+        return TokenError();
+  }
+  return NoError();
+}
+
+CheckedError Parser::ParseFlexBufferValue(flexbuffers::Builder *builder) {
+  switch (token_) {
+    case '{': {
+      auto start = builder->StartMap();
+      size_t fieldn_outer = 0;
+      auto err =
+          ParseTableDelimiters(fieldn_outer, nullptr,
+                               [&](const std::string &name, size_t &fieldn,
+                                   const StructDef *) -> CheckedError {
+                                 builder->Key(name);
+                                 ECHECK(ParseFlexBufferValue(builder));
+                                 fieldn++;
+                                 return NoError();
+                               });
+      ECHECK(err);
+      builder->EndMap(start);
+      break;
+    }
+    case '[': {
+      auto start = builder->StartVector();
+      uoffset_t count = 0;
+      ECHECK(ParseVectorDelimiters(count, [&](uoffset_t &) -> CheckedError {
+        return ParseFlexBufferValue(builder);
+      }));
+      builder->EndVector(start, false, false);
+      break;
+    }
+    case kTokenStringConstant:
+      builder->String(attribute_);
+      EXPECT(kTokenStringConstant);
+      break;
+    case kTokenIntegerConstant:
+      builder->Int(StringToInt(attribute_.c_str()));
+      EXPECT(kTokenIntegerConstant);
+      break;
+    case kTokenFloatConstant:
+      builder->Double(strtod(attribute_.c_str(), nullptr));
+      EXPECT(kTokenFloatConstant);
+      break;
+    default:
+      if (IsIdent("true")) {
+        builder->Bool(true);
+        NEXT();
+      } else if (IsIdent("false")) {
+        builder->Bool(false);
+        NEXT();
+      } else if (IsIdent("null")) {
+        builder->Null();
+        NEXT();
+      } else
+        return TokenError();
+  }
+  return NoError();
+}
+
+bool Parser::ParseFlexBuffer(const char *source, const char *source_filename,
+                             flexbuffers::Builder *builder) {
+  auto ok = !StartParseFile(source, source_filename).Check() &&
+            !ParseFlexBufferValue(builder).Check();
+  if (ok) builder->Finish();
+  return ok;
+}
+
+bool Parser::Parse(const char *source, const char **include_paths,
+                   const char *source_filename) {
+  FLATBUFFERS_ASSERT(0 == recurse_protection_counter);
+  auto r = !ParseRoot(source, include_paths, source_filename).Check();
+  FLATBUFFERS_ASSERT(0 == recurse_protection_counter);
+  return r;
+}
+
+CheckedError Parser::StartParseFile(const char *source,
+                                    const char *source_filename) {
+  file_being_parsed_ = source_filename ? source_filename : "";
+  source_ = source;
+  ResetState(source_);
+  error_.clear();
+  ECHECK(SkipByteOrderMark());
+  NEXT();
+  if (Is(kTokenEof)) return Error("input file is empty");
+  return NoError();
+}
+
+CheckedError Parser::ParseRoot(const char *source, const char **include_paths,
+                               const char *source_filename) {
+  ECHECK(DoParse(source, include_paths, source_filename, nullptr));
+
+  // Check that all types were defined.
+  for (auto it = structs_.vec.begin(); it != structs_.vec.end();) {
+    auto &struct_def = **it;
+    if (struct_def.predecl) {
+      if (opts.proto_mode) {
+        // Protos allow enums to be used before declaration, so check if that
+        // is the case here.
+        EnumDef *enum_def = nullptr;
+        for (size_t components =
+                 struct_def.defined_namespace->components.size() + 1;
+             components && !enum_def; components--) {
+          auto qualified_name =
+              struct_def.defined_namespace->GetFullyQualifiedName(
+                  struct_def.name, components - 1);
+          enum_def = LookupEnum(qualified_name);
+        }
+        if (enum_def) {
+          // This is pretty slow, but a simple solution for now.
+          auto initial_count = struct_def.refcount;
+          for (auto struct_it = structs_.vec.begin();
+               struct_it != structs_.vec.end(); ++struct_it) {
+            auto &sd = **struct_it;
+            for (auto field_it = sd.fields.vec.begin();
+                 field_it != sd.fields.vec.end(); ++field_it) {
+              auto &field = **field_it;
+              if (field.value.type.struct_def == &struct_def) {
+                field.value.type.struct_def = nullptr;
+                field.value.type.enum_def = enum_def;
+                auto &bt = field.value.type.base_type == BASE_TYPE_VECTOR
+                               ? field.value.type.element
+                               : field.value.type.base_type;
+                FLATBUFFERS_ASSERT(bt == BASE_TYPE_STRUCT);
+                bt = enum_def->underlying_type.base_type;
+                struct_def.refcount--;
+                enum_def->refcount++;
+              }
+            }
+          }
+          if (struct_def.refcount)
+            return Error("internal: " + NumToString(struct_def.refcount) + "/" +
+                         NumToString(initial_count) +
+                         " use(s) of pre-declaration enum not accounted for: " +
+                         enum_def->name);
+          structs_.dict.erase(structs_.dict.find(struct_def.name));
+          it = structs_.vec.erase(it);
+          delete &struct_def;
+          continue;  // Skip error.
+        }
+      }
+      auto err = "type referenced but not defined (check namespace): " +
+                 struct_def.name;
+      if (struct_def.original_location)
+        err += ", originally at: " + *struct_def.original_location;
+      return Error(err);
+    }
+    ++it;
+  }
+
+  // This check has to happen here and not earlier, because only now do we
+  // know for sure what the type of these are.
+  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().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)
+          return Error(
+              "only tables can be union elements in the generated language: " +
+              val.name);
+      }
+    }
+  }
+  return NoError();
+}
+
+CheckedError Parser::DoParse(const char *source, const char **include_paths,
+                             const char *source_filename,
+                             const char *include_filename) {
+  if (source_filename) {
+    if (included_files_.find(source_filename) == included_files_.end()) {
+      included_files_[source_filename] =
+          include_filename ? include_filename : "";
+      files_included_per_file_[source_filename] = std::set<std::string>();
+    } else {
+      return NoError();
+    }
+  }
+  if (!include_paths) {
+    static const char *current_directory[] = { "", nullptr };
+    include_paths = current_directory;
+  }
+  field_stack_.clear();
+  builder_.Clear();
+  // Start with a blank namespace just in case this file doesn't have one.
+  current_namespace_ = empty_namespace_;
+
+  ECHECK(StartParseFile(source, source_filename));
+
+  // Includes must come before type declarations:
+  for (;;) {
+    // Parse pre-include proto statements if any:
+    if (opts.proto_mode && (attribute_ == "option" || attribute_ == "syntax" ||
+                            attribute_ == "package")) {
+      ECHECK(ParseProtoDecl());
+    } else if (IsIdent("native_include")) {
+      NEXT();
+      vector_emplace_back(&native_included_files_, attribute_);
+      EXPECT(kTokenStringConstant);
+      EXPECT(';');
+    } else if (IsIdent("include") || (opts.proto_mode && IsIdent("import"))) {
+      NEXT();
+      if (opts.proto_mode && attribute_ == "public") NEXT();
+      auto name = flatbuffers::PosixPath(attribute_.c_str());
+      EXPECT(kTokenStringConstant);
+      // Look for the file in include_paths.
+      std::string filepath;
+      for (auto paths = include_paths; paths && *paths; paths++) {
+        filepath = flatbuffers::ConCatPathFileName(*paths, name);
+        if (FileExists(filepath.c_str())) break;
+      }
+      if (filepath.empty())
+        return Error("unable to locate include file: " + name);
+      if (source_filename)
+        files_included_per_file_[source_filename].insert(filepath);
+      if (included_files_.find(filepath) == included_files_.end()) {
+        // We found an include file that we have not parsed yet.
+        // Load it and parse it.
+        std::string contents;
+        if (!LoadFile(filepath.c_str(), true, &contents))
+          return Error("unable to load include file: " + name);
+        ECHECK(DoParse(contents.c_str(), include_paths, filepath.c_str(),
+                       name.c_str()));
+        // We generally do not want to output code for any included files:
+        if (!opts.generate_all) MarkGenerated();
+        // Reset these just in case the included file had them, and the
+        // parent doesn't.
+        root_struct_def_ = nullptr;
+        file_identifier_.clear();
+        file_extension_.clear();
+        // This is the easiest way to continue this file after an include:
+        // instead of saving and restoring all the state, we simply start the
+        // file anew. This will cause it to encounter the same include
+        // statement again, but this time it will skip it, because it was
+        // entered into included_files_.
+        // This is recursive, but only go as deep as the number of include
+        // statements.
+        if (source_filename) {
+          included_files_.erase(source_filename);
+        }
+        return DoParse(source, include_paths, source_filename,
+                       include_filename);
+      }
+      EXPECT(';');
+    } else {
+      break;
+    }
+  }
+  // Now parse all other kinds of declarations:
+  while (token_ != kTokenEof) {
+    if (opts.proto_mode) {
+      ECHECK(ParseProtoDecl());
+    } else if (IsIdent("namespace")) {
+      ECHECK(ParseNamespace());
+    } else if (token_ == '{') {
+      if (!root_struct_def_)
+        return Error("no root type set to parse json with");
+      if (builder_.GetSize()) {
+        return Error("cannot have more than one json object in a file");
+      }
+      uoffset_t toff;
+      ECHECK(ParseTable(*root_struct_def_, nullptr, &toff));
+      if (opts.size_prefixed) {
+        builder_.FinishSizePrefixed(Offset<Table>(toff), file_identifier_.length()
+                                                             ? file_identifier_.c_str()
+                                                             : nullptr);
+      } else {
+        builder_.Finish(Offset<Table>(toff), file_identifier_.length()
+                                                 ? file_identifier_.c_str()
+                                                 : nullptr);
+      }
+      // Check that JSON file doesn't contain more objects or IDL directives.
+      // Comments after JSON are allowed.
+      EXPECT(kTokenEof);
+    } else if (IsIdent("enum")) {
+      ECHECK(ParseEnum(false, nullptr));
+    } else if (IsIdent("union")) {
+      ECHECK(ParseEnum(true, nullptr));
+    } else if (IsIdent("root_type")) {
+      NEXT();
+      auto root_type = attribute_;
+      EXPECT(kTokenIdentifier);
+      ECHECK(ParseNamespacing(&root_type, nullptr));
+      if (opts.root_type.empty()) {
+        if (!SetRootType(root_type.c_str()))
+          return Error("unknown root type: " + root_type);
+        if (root_struct_def_->fixed)
+          return Error("root type must be a table");
+      }
+      EXPECT(';');
+    } else if (IsIdent("file_identifier")) {
+      NEXT();
+      file_identifier_ = attribute_;
+      EXPECT(kTokenStringConstant);
+      if (file_identifier_.length() != FlatBufferBuilder::kFileIdentifierLength)
+        return Error("file_identifier must be exactly " +
+                     NumToString(FlatBufferBuilder::kFileIdentifierLength) +
+                     " characters");
+      EXPECT(';');
+    } else if (IsIdent("file_extension")) {
+      NEXT();
+      file_extension_ = attribute_;
+      EXPECT(kTokenStringConstant);
+      EXPECT(';');
+    } else if (IsIdent("include")) {
+      return Error("includes must come before declarations");
+    } else if (IsIdent("attribute")) {
+      NEXT();
+      auto name = attribute_;
+      if (Is(kTokenIdentifier)) {
+        NEXT();
+      } else {
+        EXPECT(kTokenStringConstant);
+      }
+      EXPECT(';');
+      known_attributes_[name] = false;
+    } else if (IsIdent("rpc_service")) {
+      ECHECK(ParseService());
+    } else {
+      ECHECK(ParseDecl());
+    }
+  }
+  return NoError();
+}
+
+std::set<std::string> Parser::GetIncludedFilesRecursive(
+    const std::string &file_name) const {
+  std::set<std::string> included_files;
+  std::list<std::string> to_process;
+
+  if (file_name.empty()) return included_files;
+  to_process.push_back(file_name);
+
+  while (!to_process.empty()) {
+    std::string current = to_process.front();
+    to_process.pop_front();
+    included_files.insert(current);
+
+    // Workaround the lack of const accessor in C++98 maps.
+    auto &new_files =
+        (*const_cast<std::map<std::string, std::set<std::string>> *>(
+            &files_included_per_file_))[current];
+    for (auto it = new_files.begin(); it != new_files.end(); ++it) {
+      if (included_files.find(*it) == included_files.end())
+        to_process.push_back(*it);
+    }
+  }
+
+  return included_files;
+}
+
+// Schema serialization functionality:
+
+template<typename T> bool compareName(const T *a, const T *b) {
+  return a->defined_namespace->GetFullyQualifiedName(a->name) <
+         b->defined_namespace->GetFullyQualifiedName(b->name);
+}
+
+template<typename T> void AssignIndices(const std::vector<T *> &defvec) {
+  // Pre-sort these vectors, such that we can set the correct indices for them.
+  auto vec = defvec;
+  std::sort(vec.begin(), vec.end(), compareName<T>);
+  for (int i = 0; i < static_cast<int>(vec.size()); i++) vec[i]->index = i;
+}
+
+void Parser::Serialize() {
+  builder_.Clear();
+  AssignIndices(structs_.vec);
+  AssignIndices(enums_.vec);
+  std::vector<Offset<reflection::Object>> object_offsets;
+  for (auto it = structs_.vec.begin(); it != structs_.vec.end(); ++it) {
+    auto offset = (*it)->Serialize(&builder_, *this);
+    object_offsets.push_back(offset);
+    (*it)->serialized_location = offset.o;
+  }
+  std::vector<Offset<reflection::Enum>> enum_offsets;
+  for (auto it = enums_.vec.begin(); it != enums_.vec.end(); ++it) {
+    auto offset = (*it)->Serialize(&builder_, *this);
+    enum_offsets.push_back(offset);
+    (*it)->serialized_location = offset.o;
+  }
+  std::vector<Offset<reflection::Service>> service_offsets;
+  for (auto it = services_.vec.begin(); it != services_.vec.end(); ++it) {
+    auto offset = (*it)->Serialize(&builder_, *this);
+    service_offsets.push_back(offset);
+    (*it)->serialized_location = offset.o;
+  }
+  auto objs__ = builder_.CreateVectorOfSortedTables(&object_offsets);
+  auto enum__ = builder_.CreateVectorOfSortedTables(&enum_offsets);
+  auto fiid__ = builder_.CreateString(file_identifier_);
+  auto fext__ = builder_.CreateString(file_extension_);
+  auto serv__ = builder_.CreateVectorOfSortedTables(&service_offsets);
+  auto schema_offset =
+      reflection::CreateSchema(builder_, objs__, enum__, fiid__, fext__,
+        (root_struct_def_ ? root_struct_def_->serialized_location : 0),
+        serv__);
+  if (opts.size_prefixed) {
+    builder_.FinishSizePrefixed(schema_offset, reflection::SchemaIdentifier());
+  } else {
+    builder_.Finish(schema_offset, reflection::SchemaIdentifier());
+  }
+}
+
+static Namespace *GetNamespace(
+    const std::string &qualified_name, std::vector<Namespace *> &namespaces,
+    std::map<std::string, Namespace *> &namespaces_index) {
+  size_t dot = qualified_name.find_last_of('.');
+  std::string namespace_name = (dot != std::string::npos)
+                                   ? std::string(qualified_name.c_str(), dot)
+                                   : "";
+  Namespace *&ns = namespaces_index[namespace_name];
+
+  if (!ns) {
+    ns = new Namespace();
+    namespaces.push_back(ns);
+
+    size_t pos = 0;
+
+    for (;;) {
+      dot = qualified_name.find('.', pos);
+      if (dot == std::string::npos) { break; }
+      ns->components.push_back(qualified_name.substr(pos, dot - pos));
+      pos = dot + 1;
+    }
+  }
+
+  return ns;
+}
+
+Offset<reflection::Object> StructDef::Serialize(FlatBufferBuilder *builder,
+                                                const Parser &parser) const {
+  std::vector<Offset<reflection::Field>> field_offsets;
+  for (auto it = fields.vec.begin(); it != fields.vec.end(); ++it) {
+    field_offsets.push_back((*it)->Serialize(
+        builder, static_cast<uint16_t>(it - fields.vec.begin()), parser));
+  }
+  auto qualified_name = defined_namespace->GetFullyQualifiedName(name);
+  auto name__ = builder->CreateString(qualified_name);
+  auto flds__ = builder->CreateVectorOfSortedTables(&field_offsets);
+  auto attr__ = SerializeAttributes(builder, parser);
+  auto docs__ = parser.opts.binary_schema_comments
+                ? builder->CreateVectorOfStrings(doc_comment)
+                : 0;
+  return reflection::CreateObject(*builder, name__, flds__, fixed,
+                                  static_cast<int>(minalign),
+                                  static_cast<int>(bytesize),
+                                  attr__, docs__);
+}
+
+bool StructDef::Deserialize(Parser &parser, const reflection::Object *object) {
+  if (!DeserializeAttributes(parser, object->attributes()))
+    return false;
+  DeserializeDoc(doc_comment, object->documentation());
+  name = parser.UnqualifiedName(object->name()->str());
+  predecl = false;
+  sortbysize = attributes.Lookup("original_order") == nullptr && !fixed;
+  const auto& of = *(object->fields());
+  auto indexes = std::vector<uoffset_t>(of.size());
+  for (uoffset_t i = 0; i < of.size(); i++) indexes[of.Get(i)->id()] = i;
+  size_t tmp_struct_size = 0;
+  for (size_t i = 0; i < indexes.size(); i++) {
+    auto field = of.Get(indexes[i]);
+    auto field_def = new FieldDef();
+    if (!field_def->Deserialize(parser, field) ||
+        fields.Add(field_def->name, field_def)) {
+      delete field_def;
+      return false;
+    }
+    if (fixed) {
+      // Recompute padding since that's currently not serialized.
+      auto size = InlineSize(field_def->value.type);
+      auto next_field =
+          i + 1 < indexes.size()
+          ? of.Get(indexes[i+1])
+          : nullptr;
+      tmp_struct_size += size;
+      field_def->padding =
+          next_field ? (next_field->offset() - field_def->value.offset) - size
+                     : PaddingBytes(tmp_struct_size, minalign);
+      tmp_struct_size += field_def->padding;
+    }
+  }
+  FLATBUFFERS_ASSERT(static_cast<int>(tmp_struct_size) == object->bytesize());
+  return true;
+}
+
+Offset<reflection::Field> FieldDef::Serialize(FlatBufferBuilder *builder,
+                                              uint16_t id,
+                                              const Parser &parser) const {
+  auto name__ = builder->CreateString(name);
+  auto type__ = value.type.Serialize(builder);
+  auto attr__ = SerializeAttributes(builder, parser);
+  auto docs__ = parser.opts.binary_schema_comments
+                ? builder->CreateVectorOfStrings(doc_comment)
+                : 0;
+  return reflection::CreateField(*builder, name__, type__, id, value.offset,
+      // Is uint64>max(int64) tested?
+      IsInteger(value.type.base_type) ? StringToInt(value.constant.c_str()) : 0,
+      // result may be platform-dependent if underlying is float (not double)
+      IsFloat(value.type.base_type) ? strtod(value.constant.c_str(), nullptr)
+                                    : 0.0,
+      deprecated, required, key, attr__, docs__);
+  // TODO: value.constant is almost always "0", we could save quite a bit of
+  // space by sharing it. Same for common values of value.type.
+}
+
+bool FieldDef::Deserialize(Parser &parser, const reflection::Field *field) {
+  name = field->name()->str();
+  defined_namespace = parser.current_namespace_;
+  if (!value.type.Deserialize(parser, field->type()))
+    return false;
+  value.offset = field->offset();
+  if (IsInteger(value.type.base_type)) {
+    value.constant = NumToString(field->default_integer());
+  } else if (IsFloat(value.type.base_type)) {
+    value.constant = FloatToString(field->default_real(), 16);
+    size_t last_zero = value.constant.find_last_not_of('0');
+    if (last_zero != std::string::npos && last_zero != 0) {
+      value.constant.erase(last_zero, std::string::npos);
+    }
+  }
+  deprecated = field->deprecated();
+  required = field->required();
+  key = field->key();
+  if (!DeserializeAttributes(parser, field->attributes()))
+    return false;
+  // TODO: this should probably be handled by a separate attribute
+  if (attributes.Lookup("flexbuffer")) {
+    flexbuffer = true;
+    parser.uses_flexbuffers_ = true;
+    if (value.type.base_type != BASE_TYPE_VECTOR ||
+        value.type.element != BASE_TYPE_UCHAR)
+      return false;
+  }
+  if (auto nested = attributes.Lookup("nested_flatbuffer")) {
+    auto nested_qualified_name =
+        parser.current_namespace_->GetFullyQualifiedName(nested->constant);
+    nested_flatbuffer = parser.LookupStruct(nested_qualified_name);
+    if (!nested_flatbuffer) return false;
+  }
+  DeserializeDoc(doc_comment, field->documentation());
+  return true;
+}
+
+Offset<reflection::RPCCall> RPCCall::Serialize(FlatBufferBuilder *builder,
+                                               const Parser &parser) const {
+  auto name__ = builder->CreateString(name);
+  auto attr__ = SerializeAttributes(builder, parser);
+  auto docs__ = parser.opts.binary_schema_comments
+                ? builder->CreateVectorOfStrings(doc_comment)
+                : 0;
+  return reflection::CreateRPCCall(*builder, name__,
+                                   request->serialized_location,
+                                   response->serialized_location,
+                                   attr__, docs__);
+}
+
+bool RPCCall::Deserialize(Parser &parser, const reflection::RPCCall *call) {
+  name = call->name()->str();
+  if (!DeserializeAttributes(parser, call->attributes()))
+    return false;
+  DeserializeDoc(doc_comment, call->documentation());
+  request = parser.structs_.Lookup(call->request()->name()->str());
+  response = parser.structs_.Lookup(call->response()->name()->str());
+  if (!request || !response) { return false; }
+  return true;
+}
+
+Offset<reflection::Service> ServiceDef::Serialize(FlatBufferBuilder *builder,
+                                                  const Parser &parser) const {
+  std::vector<Offset<reflection::RPCCall>> servicecall_offsets;
+  for (auto it = calls.vec.begin(); it != calls.vec.end(); ++it) {
+    servicecall_offsets.push_back((*it)->Serialize(builder, parser));
+  }
+  auto qualified_name = defined_namespace->GetFullyQualifiedName(name);
+  auto name__ = builder->CreateString(qualified_name);
+  auto call__ = builder->CreateVector(servicecall_offsets);
+  auto attr__ = SerializeAttributes(builder, parser);
+  auto docs__ = parser.opts.binary_schema_comments
+                ? builder->CreateVectorOfStrings(doc_comment)
+                : 0;
+  return reflection::CreateService(*builder, name__, call__, attr__, docs__);
+}
+
+bool ServiceDef::Deserialize(Parser &parser,
+                             const reflection::Service *service) {
+  name = parser.UnqualifiedName(service->name()->str());
+  if (service->calls()) {
+    for (uoffset_t i = 0; i < service->calls()->size(); ++i) {
+      auto call = new RPCCall();
+      if (!call->Deserialize(parser, service->calls()->Get(i)) ||
+          calls.Add(call->name, call)) {
+        delete call;
+        return false;
+      }
+    }
+  }
+  if (!DeserializeAttributes(parser, service->attributes()))
+    return false;
+  DeserializeDoc(doc_comment, service->documentation());
+  return true;
+}
+
+Offset<reflection::Enum> EnumDef::Serialize(FlatBufferBuilder *builder,
+                                            const Parser &parser) const {
+  std::vector<Offset<reflection::EnumVal>> enumval_offsets;
+  for (auto it = vals.vec.begin(); it != vals.vec.end(); ++it) {
+    enumval_offsets.push_back((*it)->Serialize(builder, parser));
+  }
+  auto qualified_name = defined_namespace->GetFullyQualifiedName(name);
+  auto name__ = builder->CreateString(qualified_name);
+  auto vals__ = builder->CreateVector(enumval_offsets);
+  auto type__ = underlying_type.Serialize(builder);
+  auto attr__ = SerializeAttributes(builder, parser);
+  auto docs__ = parser.opts.binary_schema_comments
+                ? builder->CreateVectorOfStrings(doc_comment)
+                : 0;
+  return reflection::CreateEnum(*builder, name__, vals__, is_union, type__,
+                                attr__, docs__);
+}
+
+bool EnumDef::Deserialize(Parser &parser, const reflection::Enum *_enum) {
+  name = parser.UnqualifiedName(_enum->name()->str());
+  for (uoffset_t i = 0; i < _enum->values()->size(); ++i) {
+    auto val = new EnumVal();
+    if (!val->Deserialize(parser, _enum->values()->Get(i)) ||
+        vals.Add(val->name, val)) {
+      delete val;
+      return false;
+    }
+  }
+  is_union = _enum->is_union();
+  if (!underlying_type.Deserialize(parser, _enum->underlying_type())) {
+    return false;
+  }
+  if (!DeserializeAttributes(parser, _enum->attributes()))
+    return false;
+  DeserializeDoc(doc_comment, _enum->documentation());
+  return true;
+}
+
+Offset<reflection::EnumVal> EnumVal::Serialize(FlatBufferBuilder *builder,
+                                               const Parser &parser) const {
+  auto name__ = builder->CreateString(name);
+  auto type__ = union_type.Serialize(builder);
+  auto docs__ = parser.opts.binary_schema_comments
+                ? builder->CreateVectorOfStrings(doc_comment)
+                : 0;
+  return reflection::CreateEnumVal(*builder, name__, value,
+      union_type.struct_def ? union_type.struct_def->serialized_location : 0,
+      type__, docs__);
+}
+
+bool EnumVal::Deserialize(const Parser &parser,
+                          const reflection::EnumVal *val) {
+  name = val->name()->str();
+  value = val->value();
+  if (!union_type.Deserialize(parser, val->union_type()))
+    return false;
+  DeserializeDoc(doc_comment, val->documentation());
+  return true;
+}
+
+Offset<reflection::Type> Type::Serialize(FlatBufferBuilder *builder) const {
+  return reflection::CreateType(
+      *builder, static_cast<reflection::BaseType>(base_type),
+      static_cast<reflection::BaseType>(element),
+      struct_def ? struct_def->index : (enum_def ? enum_def->index : -1),
+      fixed_length);
+}
+
+bool Type::Deserialize(const Parser &parser, const reflection::Type *type) {
+  if (type == nullptr) return true;
+  base_type = static_cast<BaseType>(type->base_type());
+  element = static_cast<BaseType>(type->element());
+  fixed_length = type->fixed_length();
+  if (type->index() >= 0) {
+    bool is_series = type->base_type() == reflection::Vector ||
+                     type->base_type() == reflection::Array;
+    if (type->base_type() == reflection::Obj ||
+        (is_series &&
+         type->element() == reflection::Obj)) {
+      if (static_cast<size_t>(type->index()) < parser.structs_.vec.size()) {
+        struct_def = parser.structs_.vec[type->index()];
+        struct_def->refcount++;
+      } else {
+        return false;
+      }
+    } else {
+      if (static_cast<size_t>(type->index()) < parser.enums_.vec.size()) {
+        enum_def = parser.enums_.vec[type->index()];
+      } else {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+flatbuffers::Offset<
+    flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>>
+Definition::SerializeAttributes(FlatBufferBuilder *builder,
+                                const Parser &parser) const {
+  std::vector<flatbuffers::Offset<reflection::KeyValue>> attrs;
+  for (auto kv = attributes.dict.begin(); kv != attributes.dict.end(); ++kv) {
+    auto it = parser.known_attributes_.find(kv->first);
+    FLATBUFFERS_ASSERT(it != parser.known_attributes_.end());
+    if (parser.opts.binary_schema_builtins || !it->second) {
+      auto key = builder->CreateString(kv->first);
+      auto val = builder->CreateString(kv->second->constant);
+      attrs.push_back(reflection::CreateKeyValue(*builder, key, val));
+    }
+  }
+  if (attrs.size()) {
+    return builder->CreateVectorOfSortedTables(&attrs);
+  } else {
+    return 0;
+  }
+}
+
+bool Definition::DeserializeAttributes(
+    Parser &parser, const Vector<Offset<reflection::KeyValue>> *attrs) {
+  if (attrs == nullptr)
+    return true;
+  for (uoffset_t i = 0; i < attrs->size(); ++i) {
+    auto kv = attrs->Get(i);
+    auto value = new Value();
+    if (kv->value()) { value->constant = kv->value()->str(); }
+    if (attributes.Add(kv->key()->str(), value)) {
+      delete value;
+      return false;
+    }
+    parser.known_attributes_[kv->key()->str()];
+  }
+  return true;
+}
+
+/************************************************************************/
+/* DESERIALIZATION                                                      */
+/************************************************************************/
+bool Parser::Deserialize(const uint8_t *buf, const size_t size) {
+  flatbuffers::Verifier verifier(reinterpret_cast<const uint8_t *>(buf), size);
+  bool size_prefixed = false;
+  if(!reflection::SchemaBufferHasIdentifier(buf)) {
+    if (!flatbuffers::BufferHasIdentifier(buf, reflection::SchemaIdentifier(),
+                                          true))
+      return false;
+    else
+      size_prefixed = true;
+  }
+  auto verify_fn = size_prefixed ? &reflection::VerifySizePrefixedSchemaBuffer
+                                 : &reflection::VerifySchemaBuffer;
+  if (!verify_fn(verifier)) {
+    return false;
+  }
+  auto schema = size_prefixed ? reflection::GetSizePrefixedSchema(buf)
+                              : reflection::GetSchema(buf);
+  return Deserialize(schema);
+}
+
+bool Parser::Deserialize(const reflection::Schema *schema) {
+  file_identifier_ = schema->file_ident() ? schema->file_ident()->str() : "";
+  file_extension_ = schema->file_ext() ? schema->file_ext()->str() : "";
+  std::map<std::string, Namespace *> namespaces_index;
+
+  // Create defs without deserializing so references from fields to structs and
+  // enums can be resolved.
+  for (auto it = schema->objects()->begin(); it != schema->objects()->end();
+       ++it) {
+    auto struct_def = new StructDef();
+    struct_def->bytesize = it->bytesize();
+    struct_def->fixed = it->is_struct();
+    struct_def->minalign = it->minalign();
+    if (structs_.Add(it->name()->str(), struct_def)) {
+      delete struct_def;
+      return false;
+    }
+    auto type = new Type(BASE_TYPE_STRUCT, struct_def, nullptr);
+    if (types_.Add(it->name()->str(), type)) {
+      delete type;
+      return false;
+    }
+  }
+  for (auto it = schema->enums()->begin(); it != schema->enums()->end(); ++it) {
+    auto enum_def = new EnumDef();
+    if (enums_.Add(it->name()->str(), enum_def)) {
+      delete enum_def;
+      return false;
+    }
+    auto type = new Type(BASE_TYPE_UNION, nullptr, enum_def);
+    if (types_.Add(it->name()->str(), type)) {
+      delete type;
+      return false;
+    }
+  }
+
+  // Now fields can refer to structs and enums by index.
+  for (auto it = schema->objects()->begin(); it != schema->objects()->end();
+       ++it) {
+    std::string qualified_name = it->name()->str();
+    auto struct_def = structs_.Lookup(qualified_name);
+    struct_def->defined_namespace =
+        GetNamespace(qualified_name, namespaces_, namespaces_index);
+    if (!struct_def->Deserialize(*this, * it)) { return false; }
+    if (schema->root_table() == *it) { root_struct_def_ = struct_def; }
+  }
+  for (auto it = schema->enums()->begin(); it != schema->enums()->end(); ++it) {
+    std::string qualified_name = it->name()->str();
+    auto enum_def = enums_.Lookup(qualified_name);
+    enum_def->defined_namespace =
+        GetNamespace(qualified_name, namespaces_, namespaces_index);
+    if (!enum_def->Deserialize(*this, *it)) { return false; }
+  }
+
+  if (schema->services()) {
+    for (auto it = schema->services()->begin(); it != schema->services()->end();
+         ++it) {
+      std::string qualified_name = it->name()->str();
+      auto service_def = new ServiceDef();
+      service_def->defined_namespace =
+          GetNamespace(qualified_name, namespaces_, namespaces_index);
+      if (!service_def->Deserialize(*this, *it) ||
+          services_.Add(qualified_name, service_def)) {
+        delete service_def;
+        return false;
+      }
+    }
+  }
+
+  return true;
+}
+
+std::string Parser::ConformTo(const Parser &base) {
+  for (auto sit = structs_.vec.begin(); sit != structs_.vec.end(); ++sit) {
+    auto &struct_def = **sit;
+    auto qualified_name =
+        struct_def.defined_namespace->GetFullyQualifiedName(struct_def.name);
+    auto struct_def_base = base.LookupStruct(qualified_name);
+    if (!struct_def_base) continue;
+    for (auto fit = struct_def.fields.vec.begin();
+         fit != struct_def.fields.vec.end(); ++fit) {
+      auto &field = **fit;
+      auto field_base = struct_def_base->fields.Lookup(field.name);
+      if (field_base) {
+        if (field.value.offset != field_base->value.offset)
+          return "offsets differ for field: " + field.name;
+        if (field.value.constant != field_base->value.constant)
+          return "defaults differ for field: " + field.name;
+        if (!EqualByName(field.value.type, field_base->value.type))
+          return "types differ for field: " + field.name;
+      } else {
+        // Doesn't have to exist, deleting fields is fine.
+        // But we should check if there is a field that has the same offset
+        // but is incompatible (in the case of field renaming).
+        for (auto fbit = struct_def_base->fields.vec.begin();
+             fbit != struct_def_base->fields.vec.end(); ++fbit) {
+          field_base = *fbit;
+          if (field.value.offset == field_base->value.offset) {
+            if (!EqualByName(field.value.type, field_base->value.type))
+              return "field renamed to different type: " + field.name;
+            break;
+          }
+        }
+      }
+    }
+  }
+  for (auto eit = enums_.vec.begin(); eit != enums_.vec.end(); ++eit) {
+    auto &enum_def = **eit;
+    auto qualified_name =
+        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().begin(); evit != enum_def.Vals().end();
+         ++evit) {
+      auto &enum_val = **evit;
+      auto enum_val_base = enum_def_base->Lookup(enum_val.name);
+      if (enum_val_base) {
+        if (enum_val != *enum_val_base)
+          return "values differ for enum: " + enum_val.name;
+      }
+    }
+  }
+  return "";
+}
+
+}  // namespace flatbuffers
diff --git a/src/reflection.cpp b/src/reflection.cpp
new file mode 100644
index 0000000..89ce783
--- /dev/null
+++ b/src/reflection.cpp
@@ -0,0 +1,683 @@
+/*
+ * Copyright 2015 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "flatbuffers/reflection.h"
+#include "flatbuffers/util.h"
+
+// Helper functionality for reflection.
+
+namespace flatbuffers {
+
+int64_t GetAnyValueI(reflection::BaseType type, const uint8_t *data) {
+  // clang-format off
+  #define FLATBUFFERS_GET(T) static_cast<int64_t>(ReadScalar<T>(data))
+  switch (type) {
+    case reflection::UType:
+    case reflection::Bool:
+    case reflection::UByte:  return FLATBUFFERS_GET(uint8_t);
+    case reflection::Byte:   return FLATBUFFERS_GET(int8_t);
+    case reflection::Short:  return FLATBUFFERS_GET(int16_t);
+    case reflection::UShort: return FLATBUFFERS_GET(uint16_t);
+    case reflection::Int:    return FLATBUFFERS_GET(int32_t);
+    case reflection::UInt:   return FLATBUFFERS_GET(uint32_t);
+    case reflection::Long:   return FLATBUFFERS_GET(int64_t);
+    case reflection::ULong:  return FLATBUFFERS_GET(uint64_t);
+    case reflection::Float:  return FLATBUFFERS_GET(float);
+    case reflection::Double: return FLATBUFFERS_GET(double);
+    case reflection::String: {
+      auto s = reinterpret_cast<const String *>(ReadScalar<uoffset_t>(data) +
+                                                data);
+      return s ? StringToInt(s->c_str()) : 0;
+    }
+    default: return 0;  // Tables & vectors do not make sense.
+  }
+  #undef FLATBUFFERS_GET
+  // clang-format on
+}
+
+double GetAnyValueF(reflection::BaseType type, const uint8_t *data) {
+  switch (type) {
+    case reflection::Float: return static_cast<double>(ReadScalar<float>(data));
+    case reflection::Double: return ReadScalar<double>(data);
+    case reflection::String: {
+      auto s =
+          reinterpret_cast<const String *>(ReadScalar<uoffset_t>(data) + data);
+      return s ? strtod(s->c_str(), nullptr) : 0.0;
+    }
+    default: return static_cast<double>(GetAnyValueI(type, data));
+  }
+}
+
+std::string GetAnyValueS(reflection::BaseType type, const uint8_t *data,
+                         const reflection::Schema *schema, int type_index) {
+  switch (type) {
+    case reflection::Float:
+    case reflection::Double: return NumToString(GetAnyValueF(type, data));
+    case reflection::String: {
+      auto s =
+          reinterpret_cast<const String *>(ReadScalar<uoffset_t>(data) + data);
+      return s ? s->c_str() : "";
+    }
+    case reflection::Obj:
+      if (schema) {
+        // Convert the table to a string. This is mostly for debugging purposes,
+        // and does NOT promise to be JSON compliant.
+        // Also prefixes the type.
+        auto &objectdef = *schema->objects()->Get(type_index);
+        auto s = objectdef.name()->str();
+        if (objectdef.is_struct()) {
+          s += "(struct)";  // TODO: implement this as well.
+        } else {
+          auto table_field = reinterpret_cast<const Table *>(
+              ReadScalar<uoffset_t>(data) + data);
+          s += " { ";
+          auto fielddefs = objectdef.fields();
+          for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) {
+            auto &fielddef = **it;
+            if (!table_field->CheckField(fielddef.offset())) continue;
+            auto val = GetAnyFieldS(*table_field, fielddef, schema);
+            if (fielddef.type()->base_type() == reflection::String) {
+              std::string esc;
+              flatbuffers::EscapeString(val.c_str(), val.length(), &esc, true,
+                                        false);
+              val = esc;
+            }
+            s += fielddef.name()->str();
+            s += ": ";
+            s += val;
+            s += ", ";
+          }
+          s += "}";
+        }
+        return s;
+      } else {
+        return "(table)";
+      }
+    case reflection::Vector:
+      return "[(elements)]";                   // TODO: implement this as well.
+    case reflection::Union: return "(union)";  // TODO: implement this as well.
+    default: return NumToString(GetAnyValueI(type, data));
+  }
+}
+
+void SetAnyValueI(reflection::BaseType type, uint8_t *data, int64_t val) {
+  // clang-format off
+  #define FLATBUFFERS_SET(T) WriteScalar(data, static_cast<T>(val))
+  switch (type) {
+    case reflection::UType:
+    case reflection::Bool:
+    case reflection::UByte:  FLATBUFFERS_SET(uint8_t ); break;
+    case reflection::Byte:   FLATBUFFERS_SET(int8_t  ); break;
+    case reflection::Short:  FLATBUFFERS_SET(int16_t ); break;
+    case reflection::UShort: FLATBUFFERS_SET(uint16_t); break;
+    case reflection::Int:    FLATBUFFERS_SET(int32_t ); break;
+    case reflection::UInt:   FLATBUFFERS_SET(uint32_t); break;
+    case reflection::Long:   FLATBUFFERS_SET(int64_t ); break;
+    case reflection::ULong:  FLATBUFFERS_SET(uint64_t); break;
+    case reflection::Float:  FLATBUFFERS_SET(float   ); break;
+    case reflection::Double: FLATBUFFERS_SET(double  ); break;
+    // TODO: support strings
+    default: break;
+  }
+  #undef FLATBUFFERS_SET
+  // clang-format on
+}
+
+void SetAnyValueF(reflection::BaseType type, uint8_t *data, double val) {
+  switch (type) {
+    case reflection::Float: WriteScalar(data, static_cast<float>(val)); break;
+    case reflection::Double: WriteScalar(data, val); break;
+    // TODO: support strings.
+    default: SetAnyValueI(type, data, static_cast<int64_t>(val)); break;
+  }
+}
+
+void SetAnyValueS(reflection::BaseType type, uint8_t *data, const char *val) {
+  switch (type) {
+    case reflection::Float:
+    case reflection::Double:
+      SetAnyValueF(type, data, strtod(val, nullptr));
+      break;
+    // TODO: support strings.
+    default: SetAnyValueI(type, data, StringToInt(val)); break;
+  }
+}
+
+// Resize a FlatBuffer in-place by iterating through all offsets in the buffer
+// and adjusting them by "delta" if they straddle the start offset.
+// Once that is done, bytes can now be inserted/deleted safely.
+// "delta" may be negative (shrinking).
+// Unless "delta" is a multiple of the largest alignment, you'll create a small
+// amount of garbage space in the buffer (usually 0..7 bytes).
+// If your FlatBuffer's root table is not the schema's root table, you should
+// pass in your root_table type as well.
+class ResizeContext {
+ public:
+  ResizeContext(const reflection::Schema &schema, uoffset_t start, int delta,
+                std::vector<uint8_t> *flatbuf,
+                const reflection::Object *root_table = nullptr)
+      : schema_(schema),
+        startptr_(vector_data(*flatbuf) + start),
+        delta_(delta),
+        buf_(*flatbuf),
+        dag_check_(flatbuf->size() / sizeof(uoffset_t), false) {
+    auto mask = static_cast<int>(sizeof(largest_scalar_t) - 1);
+    delta_ = (delta_ + mask) & ~mask;
+    if (!delta_) return;  // We can't shrink by less than largest_scalar_t.
+    // Now change all the offsets by delta_.
+    auto root = GetAnyRoot(vector_data(buf_));
+    Straddle<uoffset_t, 1>(vector_data(buf_), root, vector_data(buf_));
+    ResizeTable(root_table ? *root_table : *schema.root_table(), root);
+    // We can now add or remove bytes at start.
+    if (delta_ > 0)
+      buf_.insert(buf_.begin() + start, delta_, 0);
+    else
+      buf_.erase(buf_.begin() + start, buf_.begin() + start - delta_);
+  }
+
+  // Check if the range between first (lower address) and second straddles
+  // the insertion point. If it does, change the offset at offsetloc (of
+  // type T, with direction D).
+  template<typename T, int D>
+  void Straddle(const void *first, const void *second, void *offsetloc) {
+    if (first <= startptr_ && second >= startptr_) {
+      WriteScalar<T>(offsetloc, ReadScalar<T>(offsetloc) + delta_ * D);
+      DagCheck(offsetloc) = true;
+    }
+  }
+
+  // This returns a boolean that records if the corresponding offset location
+  // has been modified already. If so, we can't even read the corresponding
+  // offset, since it is pointing to a location that is illegal until the
+  // resize actually happens.
+  // This must be checked for every offset, since we can't know which offsets
+  // will straddle and which won't.
+  uint8_t &DagCheck(const void *offsetloc) {
+    auto dag_idx = reinterpret_cast<const uoffset_t *>(offsetloc) -
+                   reinterpret_cast<const uoffset_t *>(vector_data(buf_));
+    return dag_check_[dag_idx];
+  }
+
+  void ResizeTable(const reflection::Object &objectdef, Table *table) {
+    if (DagCheck(table)) return;  // Table already visited.
+    auto vtable = table->GetVTable();
+    // Early out: since all fields inside the table must point forwards in
+    // memory, if the insertion point is before the table we can stop here.
+    auto tableloc = reinterpret_cast<uint8_t *>(table);
+    if (startptr_ <= tableloc) {
+      // Check if insertion point is between the table and a vtable that
+      // precedes it. This can't happen in current construction code, but check
+      // just in case we ever change the way flatbuffers are built.
+      Straddle<soffset_t, -1>(vtable, table, table);
+    } else {
+      // Check each field.
+      auto fielddefs = objectdef.fields();
+      for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) {
+        auto &fielddef = **it;
+        auto base_type = fielddef.type()->base_type();
+        // Ignore scalars.
+        if (base_type <= reflection::Double) continue;
+        // Ignore fields that are not stored.
+        auto offset = table->GetOptionalFieldOffset(fielddef.offset());
+        if (!offset) continue;
+        // Ignore structs.
+        auto subobjectdef =
+            base_type == reflection::Obj
+                ? schema_.objects()->Get(fielddef.type()->index())
+                : nullptr;
+        if (subobjectdef && subobjectdef->is_struct()) continue;
+        // Get this fields' offset, and read it if safe.
+        auto offsetloc = tableloc + offset;
+        if (DagCheck(offsetloc)) continue;  // This offset already visited.
+        auto ref = offsetloc + ReadScalar<uoffset_t>(offsetloc);
+        Straddle<uoffset_t, 1>(offsetloc, ref, offsetloc);
+        // Recurse.
+        switch (base_type) {
+          case reflection::Obj: {
+            ResizeTable(*subobjectdef, reinterpret_cast<Table *>(ref));
+            break;
+          }
+          case reflection::Vector: {
+            auto elem_type = fielddef.type()->element();
+            if (elem_type != reflection::Obj && elem_type != reflection::String)
+              break;
+            auto vec = reinterpret_cast<Vector<uoffset_t> *>(ref);
+            auto elemobjectdef =
+                elem_type == reflection::Obj
+                    ? schema_.objects()->Get(fielddef.type()->index())
+                    : nullptr;
+            if (elemobjectdef && elemobjectdef->is_struct()) break;
+            for (uoffset_t i = 0; i < vec->size(); i++) {
+              auto loc = vec->Data() + i * sizeof(uoffset_t);
+              if (DagCheck(loc)) continue;  // This offset already visited.
+              auto dest = loc + vec->Get(i);
+              Straddle<uoffset_t, 1>(loc, dest, loc);
+              if (elemobjectdef)
+                ResizeTable(*elemobjectdef, reinterpret_cast<Table *>(dest));
+            }
+            break;
+          }
+          case reflection::Union: {
+            ResizeTable(GetUnionType(schema_, objectdef, fielddef, *table),
+                        reinterpret_cast<Table *>(ref));
+            break;
+          }
+          case reflection::String: break;
+          default: FLATBUFFERS_ASSERT(false);
+        }
+      }
+      // Check if the vtable offset points beyond the insertion point.
+      // Must do this last, since GetOptionalFieldOffset above still reads
+      // this value.
+      Straddle<soffset_t, -1>(table, vtable, table);
+    }
+  }
+
+  void operator=(const ResizeContext &rc);
+
+ private:
+  const reflection::Schema &schema_;
+  uint8_t *startptr_;
+  int delta_;
+  std::vector<uint8_t> &buf_;
+  std::vector<uint8_t> dag_check_;
+};
+
+void SetString(const reflection::Schema &schema, const std::string &val,
+               const String *str, std::vector<uint8_t> *flatbuf,
+               const reflection::Object *root_table) {
+  auto delta = static_cast<int>(val.size()) - static_cast<int>(str->size());
+  auto str_start = static_cast<uoffset_t>(
+      reinterpret_cast<const uint8_t *>(str) - vector_data(*flatbuf));
+  auto start = str_start + static_cast<uoffset_t>(sizeof(uoffset_t));
+  if (delta) {
+    // Clear the old string, since we don't want parts of it remaining.
+    memset(vector_data(*flatbuf) + start, 0, str->size());
+    // Different size, we must expand (or contract).
+    ResizeContext(schema, start, delta, flatbuf, root_table);
+    // Set the new length.
+    WriteScalar(vector_data(*flatbuf) + str_start,
+                static_cast<uoffset_t>(val.size()));
+  }
+  // Copy new data. Safe because we created the right amount of space.
+  memcpy(vector_data(*flatbuf) + start, val.c_str(), val.size() + 1);
+}
+
+uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize,
+                         const VectorOfAny *vec, uoffset_t num_elems,
+                         uoffset_t elem_size, std::vector<uint8_t> *flatbuf,
+                         const reflection::Object *root_table) {
+  auto delta_elem = static_cast<int>(newsize) - static_cast<int>(num_elems);
+  auto delta_bytes = delta_elem * static_cast<int>(elem_size);
+  auto vec_start =
+      reinterpret_cast<const uint8_t *>(vec) - vector_data(*flatbuf);
+  auto start = static_cast<uoffset_t>(vec_start + sizeof(uoffset_t) +
+                                      elem_size * num_elems);
+  if (delta_bytes) {
+    if (delta_elem < 0) {
+      // Clear elements we're throwing away, since some might remain in the
+      // buffer.
+      auto size_clear = -delta_elem * elem_size;
+      memset(vector_data(*flatbuf) + start - size_clear, 0, size_clear);
+    }
+    ResizeContext(schema, start, delta_bytes, flatbuf, root_table);
+    WriteScalar(vector_data(*flatbuf) + vec_start, newsize);  // Length field.
+    // Set new elements to 0.. this can be overwritten by the caller.
+    if (delta_elem > 0) {
+      memset(vector_data(*flatbuf) + start, 0, delta_elem * elem_size);
+    }
+  }
+  return vector_data(*flatbuf) + start;
+}
+
+const uint8_t *AddFlatBuffer(std::vector<uint8_t> &flatbuf,
+                             const uint8_t *newbuf, size_t newlen) {
+  // Align to sizeof(uoffset_t) past sizeof(largest_scalar_t) since we're
+  // going to chop off the root offset.
+  while ((flatbuf.size() & (sizeof(uoffset_t) - 1)) ||
+         !(flatbuf.size() & (sizeof(largest_scalar_t) - 1))) {
+    flatbuf.push_back(0);
+  }
+  auto insertion_point = static_cast<uoffset_t>(flatbuf.size());
+  // Insert the entire FlatBuffer minus the root pointer.
+  flatbuf.insert(flatbuf.end(), newbuf + sizeof(uoffset_t), newbuf + newlen);
+  auto root_offset = ReadScalar<uoffset_t>(newbuf) - sizeof(uoffset_t);
+  return vector_data(flatbuf) + insertion_point + root_offset;
+}
+
+void CopyInline(FlatBufferBuilder &fbb, const reflection::Field &fielddef,
+                const Table &table, size_t align, size_t size) {
+  fbb.Align(align);
+  fbb.PushBytes(table.GetStruct<const uint8_t *>(fielddef.offset()), size);
+  fbb.TrackField(fielddef.offset(), fbb.GetSize());
+}
+
+Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
+                                const reflection::Schema &schema,
+                                const reflection::Object &objectdef,
+                                const Table &table, bool use_string_pooling) {
+  // Before we can construct the table, we have to first generate any
+  // subobjects, and collect their offsets.
+  std::vector<uoffset_t> offsets;
+  auto fielddefs = objectdef.fields();
+  for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) {
+    auto &fielddef = **it;
+    // Skip if field is not present in the source.
+    if (!table.CheckField(fielddef.offset())) continue;
+    uoffset_t offset = 0;
+    switch (fielddef.type()->base_type()) {
+      case reflection::String: {
+        offset = use_string_pooling
+                     ? fbb.CreateSharedString(GetFieldS(table, fielddef)).o
+                     : fbb.CreateString(GetFieldS(table, fielddef)).o;
+        break;
+      }
+      case reflection::Obj: {
+        auto &subobjectdef = *schema.objects()->Get(fielddef.type()->index());
+        if (!subobjectdef.is_struct()) {
+          offset =
+              CopyTable(fbb, schema, subobjectdef, *GetFieldT(table, fielddef))
+                  .o;
+        }
+        break;
+      }
+      case reflection::Union: {
+        auto &subobjectdef = GetUnionType(schema, objectdef, fielddef, table);
+        offset =
+            CopyTable(fbb, schema, subobjectdef, *GetFieldT(table, fielddef)).o;
+        break;
+      }
+      case reflection::Vector: {
+        auto vec =
+            table.GetPointer<const Vector<Offset<Table>> *>(fielddef.offset());
+        auto element_base_type = fielddef.type()->element();
+        auto elemobjectdef =
+            element_base_type == reflection::Obj
+                ? schema.objects()->Get(fielddef.type()->index())
+                : nullptr;
+        switch (element_base_type) {
+          case reflection::String: {
+            std::vector<Offset<const String *>> elements(vec->size());
+            auto vec_s = reinterpret_cast<const Vector<Offset<String>> *>(vec);
+            for (uoffset_t i = 0; i < vec_s->size(); i++) {
+              elements[i] = use_string_pooling
+                                ? fbb.CreateSharedString(vec_s->Get(i)).o
+                                : fbb.CreateString(vec_s->Get(i)).o;
+            }
+            offset = fbb.CreateVector(elements).o;
+            break;
+          }
+          case reflection::Obj: {
+            if (!elemobjectdef->is_struct()) {
+              std::vector<Offset<const Table *>> elements(vec->size());
+              for (uoffset_t i = 0; i < vec->size(); i++) {
+                elements[i] =
+                    CopyTable(fbb, schema, *elemobjectdef, *vec->Get(i));
+              }
+              offset = fbb.CreateVector(elements).o;
+              break;
+            }
+          }
+          FLATBUFFERS_FALLTHROUGH(); // fall thru
+          default: {  // Scalars and structs.
+            auto element_size = GetTypeSize(element_base_type);
+            if (elemobjectdef && elemobjectdef->is_struct())
+              element_size = elemobjectdef->bytesize();
+            fbb.StartVector(vec->size(), element_size);
+            fbb.PushBytes(vec->Data(), element_size * vec->size());
+            offset = fbb.EndVector(vec->size());
+            break;
+          }
+        }
+        break;
+      }
+      default:  // Scalars.
+        break;
+    }
+    if (offset) { offsets.push_back(offset); }
+  }
+  // Now we can build the actual table from either offsets or scalar data.
+  auto start = objectdef.is_struct() ? fbb.StartStruct(objectdef.minalign())
+                                     : fbb.StartTable();
+  size_t offset_idx = 0;
+  for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) {
+    auto &fielddef = **it;
+    if (!table.CheckField(fielddef.offset())) continue;
+    auto base_type = fielddef.type()->base_type();
+    switch (base_type) {
+      case reflection::Obj: {
+        auto &subobjectdef = *schema.objects()->Get(fielddef.type()->index());
+        if (subobjectdef.is_struct()) {
+          CopyInline(fbb, fielddef, table, subobjectdef.minalign(),
+                     subobjectdef.bytesize());
+          break;
+        }
+      }
+      FLATBUFFERS_FALLTHROUGH(); // fall thru
+      case reflection::Union:
+      case reflection::String:
+      case reflection::Vector:
+        fbb.AddOffset(fielddef.offset(), Offset<void>(offsets[offset_idx++]));
+        break;
+      default: {  // Scalars.
+        auto size = GetTypeSize(base_type);
+        CopyInline(fbb, fielddef, table, size, size);
+        break;
+      }
+    }
+  }
+  FLATBUFFERS_ASSERT(offset_idx == offsets.size());
+  if (objectdef.is_struct()) {
+    fbb.ClearOffsets();
+    return fbb.EndStruct();
+  } else {
+    return fbb.EndTable(start);
+  }
+}
+
+bool VerifyStruct(flatbuffers::Verifier &v,
+                  const flatbuffers::Table &parent_table,
+                  voffset_t field_offset, const reflection::Object &obj,
+                  bool required) {
+  auto offset = parent_table.GetOptionalFieldOffset(field_offset);
+  if (required && !offset) { return false; }
+
+  return !offset ||
+         v.Verify(reinterpret_cast<const uint8_t *>(&parent_table), offset,
+                  obj.bytesize());
+}
+
+bool VerifyVectorOfStructs(flatbuffers::Verifier &v,
+                           const flatbuffers::Table &parent_table,
+                           voffset_t field_offset,
+                           const reflection::Object &obj, bool required) {
+  auto p = parent_table.GetPointer<const uint8_t *>(field_offset);
+  if (required && !p) { return false; }
+
+  return !p || v.VerifyVectorOrString(p, obj.bytesize());
+}
+
+// forward declare to resolve cyclic deps between VerifyObject and VerifyVector
+bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
+                  const reflection::Object &obj,
+                  const flatbuffers::Table *table, bool required);
+
+bool VerifyVector(flatbuffers::Verifier &v, const reflection::Schema &schema,
+                  const flatbuffers::Table &table,
+                  const reflection::Field &vec_field) {
+  FLATBUFFERS_ASSERT(vec_field.type()->base_type() == reflection::Vector);
+  if (!table.VerifyField<uoffset_t>(v, vec_field.offset())) return false;
+
+  switch (vec_field.type()->element()) {
+    case reflection::None: FLATBUFFERS_ASSERT(false); break;
+    case reflection::UType:
+      return v.VerifyVector(flatbuffers::GetFieldV<uint8_t>(table, vec_field));
+    case reflection::Bool:
+    case reflection::Byte:
+    case reflection::UByte:
+      return v.VerifyVector(flatbuffers::GetFieldV<int8_t>(table, vec_field));
+    case reflection::Short:
+    case reflection::UShort:
+      return v.VerifyVector(flatbuffers::GetFieldV<int16_t>(table, vec_field));
+    case reflection::Int:
+    case reflection::UInt:
+      return v.VerifyVector(flatbuffers::GetFieldV<int32_t>(table, vec_field));
+    case reflection::Long:
+    case reflection::ULong:
+      return v.VerifyVector(flatbuffers::GetFieldV<int64_t>(table, vec_field));
+    case reflection::Float:
+      return v.VerifyVector(flatbuffers::GetFieldV<float>(table, vec_field));
+    case reflection::Double:
+      return v.VerifyVector(flatbuffers::GetFieldV<double>(table, vec_field));
+    case reflection::String: {
+      auto vec_string =
+          flatbuffers::GetFieldV<flatbuffers::Offset<flatbuffers::String>>(
+              table, vec_field);
+      if (v.VerifyVector(vec_string) && v.VerifyVectorOfStrings(vec_string)) {
+        return true;
+      } else {
+        return false;
+      }
+    }
+    case reflection::Vector: FLATBUFFERS_ASSERT(false); break;
+    case reflection::Obj: {
+      auto obj = schema.objects()->Get(vec_field.type()->index());
+      if (obj->is_struct()) {
+        if (!VerifyVectorOfStructs(v, table, vec_field.offset(), *obj,
+                                   vec_field.required())) {
+          return false;
+        }
+      } else {
+        auto vec =
+            flatbuffers::GetFieldV<flatbuffers::Offset<flatbuffers::Table>>(
+                table, vec_field);
+        if (!v.VerifyVector(vec)) return false;
+        if (vec) {
+          for (uoffset_t j = 0; j < vec->size(); j++) {
+            if (!VerifyObject(v, schema, *obj, vec->Get(j), true)) {
+              return false;
+            }
+          }
+        }
+      }
+      return true;
+    }
+    case reflection::Union: FLATBUFFERS_ASSERT(false); break;
+    default: FLATBUFFERS_ASSERT(false); break;
+  }
+
+  return false;
+}
+
+bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
+                  const reflection::Object &obj,
+                  const flatbuffers::Table *table, bool required) {
+  if (!table) {
+    if (!required)
+      return true;
+    else
+      return false;
+  }
+
+  if (!table->VerifyTableStart(v)) return false;
+
+  for (uoffset_t i = 0; i < obj.fields()->size(); i++) {
+    auto field_def = obj.fields()->Get(i);
+    switch (field_def->type()->base_type()) {
+      case reflection::None: FLATBUFFERS_ASSERT(false); break;
+      case reflection::UType:
+        if (!table->VerifyField<uint8_t>(v, field_def->offset())) return false;
+        break;
+      case reflection::Bool:
+      case reflection::Byte:
+      case reflection::UByte:
+        if (!table->VerifyField<int8_t>(v, field_def->offset())) return false;
+        break;
+      case reflection::Short:
+      case reflection::UShort:
+        if (!table->VerifyField<int16_t>(v, field_def->offset())) return false;
+        break;
+      case reflection::Int:
+      case reflection::UInt:
+        if (!table->VerifyField<int32_t>(v, field_def->offset())) return false;
+        break;
+      case reflection::Long:
+      case reflection::ULong:
+        if (!table->VerifyField<int64_t>(v, field_def->offset())) return false;
+        break;
+      case reflection::Float:
+        if (!table->VerifyField<float>(v, field_def->offset())) return false;
+        break;
+      case reflection::Double:
+        if (!table->VerifyField<double>(v, field_def->offset())) return false;
+        break;
+      case reflection::String:
+        if (!table->VerifyField<uoffset_t>(v, field_def->offset()) ||
+            !v.VerifyString(flatbuffers::GetFieldS(*table, *field_def))) {
+          return false;
+        }
+        break;
+      case reflection::Vector:
+        if (!VerifyVector(v, schema, *table, *field_def)) return false;
+        break;
+      case reflection::Obj: {
+        auto child_obj = schema.objects()->Get(field_def->type()->index());
+        if (child_obj->is_struct()) {
+          if (!VerifyStruct(v, *table, field_def->offset(), *child_obj,
+                            field_def->required())) {
+            return false;
+          }
+        } else {
+          if (!VerifyObject(v, schema, *child_obj,
+                            flatbuffers::GetFieldT(*table, *field_def),
+                            field_def->required())) {
+            return false;
+          }
+        }
+        break;
+      }
+      case reflection::Union: {
+        //  get union type from the prev field
+        voffset_t utype_offset = field_def->offset() - sizeof(voffset_t);
+        auto utype = table->GetField<uint8_t>(utype_offset, 0);
+        if (utype != 0) {
+          // Means we have this union field present
+          auto fb_enum = schema.enums()->Get(field_def->type()->index());
+          auto child_obj = fb_enum->values()->Get(utype)->object();
+          if (!VerifyObject(v, schema, *child_obj,
+                            flatbuffers::GetFieldT(*table, *field_def),
+                            field_def->required())) {
+            return false;
+          }
+        }
+        break;
+      }
+      default: FLATBUFFERS_ASSERT(false); break;
+    }
+  }
+
+  if (!v.EndTable()) return false;
+
+  return true;
+}
+
+bool Verify(const reflection::Schema &schema, const reflection::Object &root,
+            const uint8_t *buf, size_t length) {
+  Verifier v(buf, length);
+  return VerifyObject(v, schema, root, flatbuffers::GetAnyRoot(buf), true);
+}
+
+}  // namespace flatbuffers
diff --git a/src/util.cpp b/src/util.cpp
new file mode 100644
index 0000000..5483cee
--- /dev/null
+++ b/src/util.cpp
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2016 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// clang-format off
+// Dont't remove `format off`, it prevent reordering of win-includes.
+#ifdef _WIN32
+#  ifndef WIN32_LEAN_AND_MEAN
+#    define WIN32_LEAN_AND_MEAN
+#  endif
+#  ifndef NOMINMAX
+#    define NOMINMAX
+#  endif
+#  ifdef _MSC_VER
+#    include <crtdbg.h>
+#  endif
+#  include <windows.h>  // Must be included before <direct.h>
+#  include <direct.h>
+#  include <winbase.h>
+#  undef interface  // This is also important because of reasons
+#else
+#  include <limits.h>
+#endif
+// clang-format on
+
+#include "flatbuffers/base.h"
+#include "flatbuffers/util.h"
+
+#include <sys/stat.h>
+#include <clocale>
+#include <fstream>
+
+namespace flatbuffers {
+
+bool FileExistsRaw(const char *name) {
+  std::ifstream ifs(name);
+  return ifs.good();
+}
+
+bool LoadFileRaw(const char *name, bool binary, std::string *buf) {
+  if (DirExists(name)) return false;
+  std::ifstream ifs(name, binary ? std::ifstream::binary : std::ifstream::in);
+  if (!ifs.is_open()) return false;
+  if (binary) {
+    // The fastest way to read a file into a string.
+    ifs.seekg(0, std::ios::end);
+    auto size = ifs.tellg();
+    (*buf).resize(static_cast<size_t>(size));
+    ifs.seekg(0, std::ios::beg);
+    ifs.read(&(*buf)[0], (*buf).size());
+  } else {
+    // This is slower, but works correctly on all platforms for text files.
+    std::ostringstream oss;
+    oss << ifs.rdbuf();
+    *buf = oss.str();
+  }
+  return !ifs.bad();
+}
+
+static LoadFileFunction g_load_file_function = LoadFileRaw;
+static FileExistsFunction g_file_exists_function = FileExistsRaw;
+
+bool LoadFile(const char *name, bool binary, std::string *buf) {
+  FLATBUFFERS_ASSERT(g_load_file_function);
+  return g_load_file_function(name, binary, buf);
+}
+
+bool FileExists(const char *name) {
+  FLATBUFFERS_ASSERT(g_file_exists_function);
+  return g_file_exists_function(name);
+}
+
+bool DirExists(const char *name) {
+  // clang-format off
+
+  #ifdef _WIN32
+    #define flatbuffers_stat _stat
+    #define FLATBUFFERS_S_IFDIR _S_IFDIR
+  #else
+    #define flatbuffers_stat stat
+    #define FLATBUFFERS_S_IFDIR S_IFDIR
+  #endif
+  // clang-format on
+  struct flatbuffers_stat file_info;
+  if (flatbuffers_stat(name, &file_info) != 0) return false;
+  return (file_info.st_mode & FLATBUFFERS_S_IFDIR) != 0;
+}
+
+LoadFileFunction SetLoadFileFunction(LoadFileFunction load_file_function) {
+  LoadFileFunction previous_function = g_load_file_function;
+  g_load_file_function = load_file_function ? load_file_function : LoadFileRaw;
+  return previous_function;
+}
+
+FileExistsFunction SetFileExistsFunction(
+    FileExistsFunction file_exists_function) {
+  FileExistsFunction previous_function = g_file_exists_function;
+  g_file_exists_function =
+      file_exists_function ? file_exists_function : FileExistsRaw;
+  return previous_function;
+}
+
+bool SaveFile(const char *name, const char *buf, size_t len, bool binary) {
+  std::ofstream ofs(name, binary ? std::ofstream::binary : std::ofstream::out);
+  if (!ofs.is_open()) return false;
+  ofs.write(buf, len);
+  return !ofs.bad();
+}
+
+// We internally store paths in posix format ('/'). Paths supplied
+// by the user should go through PosixPath to ensure correct behavior
+// on Windows when paths are string-compared.
+
+static const char kPathSeparatorWindows = '\\';
+static const char *PathSeparatorSet = "\\/";  // Intentionally no ':'
+
+std::string StripExtension(const std::string &filepath) {
+  size_t i = filepath.find_last_of('.');
+  return i != std::string::npos ? filepath.substr(0, i) : filepath;
+}
+
+std::string GetExtension(const std::string &filepath) {
+  size_t i = filepath.find_last_of('.');
+  return i != std::string::npos ? filepath.substr(i + 1) : "";
+}
+
+std::string StripPath(const std::string &filepath) {
+  size_t i = filepath.find_last_of(PathSeparatorSet);
+  return i != std::string::npos ? filepath.substr(i + 1) : filepath;
+}
+
+std::string StripFileName(const std::string &filepath) {
+  size_t i = filepath.find_last_of(PathSeparatorSet);
+  return i != std::string::npos ? filepath.substr(0, i) : "";
+}
+
+std::string ConCatPathFileName(const std::string &path,
+                               const std::string &filename) {
+  std::string filepath = path;
+  if (filepath.length()) {
+    char &filepath_last_character = string_back(filepath);
+    if (filepath_last_character == kPathSeparatorWindows) {
+      filepath_last_character = kPathSeparator;
+    } else if (filepath_last_character != kPathSeparator) {
+      filepath += kPathSeparator;
+    }
+  }
+  filepath += filename;
+  // Ignore './' at the start of filepath.
+  if (filepath[0] == '.' && filepath[1] == kPathSeparator) {
+    filepath.erase(0, 2);
+  }
+  return filepath;
+}
+
+std::string PosixPath(const char *path) {
+  std::string p = path;
+  std::replace(p.begin(), p.end(), '\\', '/');
+  return p;
+}
+
+void EnsureDirExists(const std::string &filepath) {
+  auto parent = StripFileName(filepath);
+  if (parent.length()) EnsureDirExists(parent);
+    // clang-format off
+
+  #ifdef _WIN32
+    (void)_mkdir(filepath.c_str());
+  #else
+    mkdir(filepath.c_str(), S_IRWXU|S_IRGRP|S_IXGRP);
+  #endif
+  // clang-format on
+}
+
+std::string AbsolutePath(const std::string &filepath) {
+  // clang-format off
+
+  #ifdef FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION
+    return filepath;
+  #else
+    #ifdef _WIN32
+      char abs_path[MAX_PATH];
+      return GetFullPathNameA(filepath.c_str(), MAX_PATH, abs_path, nullptr)
+    #else
+      char abs_path[PATH_MAX];
+      return realpath(filepath.c_str(), abs_path)
+    #endif
+      ? abs_path
+      : filepath;
+  #endif // FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION
+  // clang-format on
+}
+
+// Locale-independent code.
+#if defined(FLATBUFFERS_LOCALE_INDEPENDENT) && \
+    (FLATBUFFERS_LOCALE_INDEPENDENT > 0)
+
+// clang-format off
+// Allocate locale instance at startup of application.
+ClassicLocale ClassicLocale::instance_;
+
+#ifdef _MSC_VER
+  ClassicLocale::ClassicLocale()
+    : locale_(_create_locale(LC_ALL, "C")) {}
+  ClassicLocale::~ClassicLocale() { _free_locale(locale_); }
+#else
+  ClassicLocale::ClassicLocale()
+    : locale_(newlocale(LC_ALL, "C", nullptr)) {}
+  ClassicLocale::~ClassicLocale() { freelocale(locale_); }
+#endif
+// clang-format on
+
+#endif  // !FLATBUFFERS_LOCALE_INDEPENDENT
+
+std::string RemoveStringQuotes(const std::string &s) {
+  auto ch = *s.c_str();
+  return ((s.size() >= 2) && (ch == '\"' || ch == '\'') &&
+          (ch == string_back(s)))
+             ? s.substr(1, s.length() - 2)
+             : s;
+}
+
+bool SetGlobalTestLocale(const char *locale_name, std::string *_value) {
+  const auto the_locale = setlocale(LC_ALL, locale_name);
+  if (!the_locale) return false;
+  if (_value) *_value = std::string(the_locale);
+  return true;
+}
+
+bool ReadEnvironmentVariable(const char *var_name, std::string *_value) {
+  #ifdef _MSC_VER
+  __pragma(warning(disable : 4996)); // _CRT_SECURE_NO_WARNINGS
+  #endif
+  auto env_str = std::getenv(var_name);
+  if (!env_str) return false;
+  if (_value) *_value = std::string(env_str);
+  return true;
+}
+
+void SetupDefaultCRTReportMode() {
+  // clang-format off
+
+  #ifdef _MSC_VER
+    // 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, dbg_mode);
+    _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
+    // The assert from <assert.h> reports to _CRT_ERROR channel
+    _CrtSetReportMode(_CRT_ERROR, dbg_mode);
+    _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT);
+    // Internal CRT assert channel?
+    _CrtSetReportMode(_CRT_ASSERT, dbg_mode);
+    _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT);
+  #endif
+
+  // clang-format on
+}
+
+}  // namespace flatbuffers
